#!/bin/bash
#JackLee_CN Edit Add row in 5292 Agrs url to diy winetricks file server url
#Add W_DOWNLOADURLS to winetricks file server Agrs next
#add S_HTTPS=https:// to Agrs Next yes or no url agrs
#EDIT row in 1007 POSIX to Bourne-Again 
WINETRICKS_VERSION=20210402

# FIXME: XDG_CACHE_HOME is defined twice, clean this up
XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}"

W_COUNTRY=""
W_PREFIXES_ROOT="${WINE_PREFIXES:-$XDG_DATA_HOME/wineprefixes}"

# For temp files before $WINEPREFIX is available:
if [ -x "$(command -v mktemp 2>/dev/null)" ] ; then
    W_TMP_EARLY="$(mktemp -d "${TMPDIR:-/tmp}/winetricks.XXXXXXXX")"
elif [ -w "$TMPDIR" ] ; then
    W_TMP_EARLY="$TMPDIR"
else
    W_TMP_EARLY="/tmp"
fi

#---- Public Functions ----

# Ask permission to continue
w_askpermission()
{
    echo "------------------------------------------------------"
    echo "$@"
    echo "------------------------------------------------------"

    if test "$W_OPT_UNATTENDED"; then
        _W_timeout="--timeout 5"
    fi

    case $WINETRICKS_GUI in
        zenity) $WINETRICKS_GUI "$_W_timeout" --question --title=winetricks --text="$(echo "$@" | sed 's,\\\\,\\\\\\\\,g')" --no-wrap;;
        kdialog) $WINETRICKS_GUI --title winetricks --warningcontinuecancel "$@" ;;
        none)
            if [ -n "$_W_timeout" ]; then
                # -t / TMOUT don't seem to be portable, so just assume yes in unattended mode
                w_info "Unattended mode, not prompting for confirmation"
            else
                printf %s "Press Y or N, then Enter: "
                read -r response
                test "$response" = Y || test "$response" = y
            fi
    esac

    if test $? -ne 0; then
        case $LANG in
            uk*) w_die "Операція скасована." ;;
            pl*) w_die "Anulowano operację, opuszczanie." ;;
            *) w_die "Operation cancelled, quitting." ;;
        esac
        exec false
    fi

    unset _W_timeout
}

# Display info message.  Time out quickly if user doesn't click.
w_info()
{
    # If $WINETRICKS_SUPER_QUIET is set, w_info is a no-op:
    if [ -z "$WINETRICKS_SUPER_QUIET" ] ; then
        echo "------------------------------------------------------"
        echo "$@"
        echo "------------------------------------------------------"
    fi

    _W_timeout="--timeout 3"

    case $WINETRICKS_GUI in
        zenity) $WINETRICKS_GUI "$_W_timeout" --info --title=winetricks --text="$(echo "$@" | sed 's,\\\\,\\\\\\\\,g')" --no-wrap;;
        kdialog) $WINETRICKS_GUI --title winetricks --msgbox "$@" ;;
        none) ;;
    esac

    unset _W_timeout
}

# Display warning message to stderr (since it is called inside redirected code)
w_warn()
{
    # If $WINETRICKS_SUPER_QUIET is set, w_info is a no-op:
    if [ -z "$WINETRICKS_SUPER_QUIET" ] ; then
        echo "------------------------------------------------------"
        echo "$@"
        echo "------------------------------------------------------"
    fi

    if test "$W_OPT_UNATTENDED"; then
        _W_timeout="--timeout 5"
    fi

    case $WINETRICKS_GUI in
        zenity) $WINETRICKS_GUI "$_W_timeout" --error --title=winetricks --text="$(echo "$@" | sed 's,\\\\,\\\\\\\\,g')";;
        kdialog) $WINETRICKS_GUI --title winetricks --error "$@" ;;
        none) ;;
    esac

    unset _W_timeout
}

# Display warning message to stderr (since it is called inside redirected code)
# And give gui user option to cancel (for when used in a loop)
# If user cancels, exit status is 1
w_warn_cancel()
{
    echo "------------------------------------------------------" >&2
    echo "$@" >&2
    echo "------------------------------------------------------" >&2

    if test "$W_OPT_UNATTENDED"; then
        _W_timeout="--timeout 5"
    fi

    # Zenity has no cancel button, but will set status to 1 if you click the go-away X
    case $WINETRICKS_GUI in
        zenity) $WINETRICKS_GUI "$_W_timeout" --error --title=winetricks --text="$(echo "$@" | sed 's,\\\\,\\\\\\\\,g')";;
        kdialog) $WINETRICKS_GUI --title winetricks --warningcontinuecancel "$@" ;;
        none) ;;
    esac

    # can't unset, it clears status
}

# Display fatal error message and terminate script
w_die()
{
    w_warn "$@"

    exit 1
}

# Kill all instances of a process in a safe way (Solaris killall kills _everything_)
w_killall()
{
    # shellcheck disable=SC2046,SC2086
    kill -s KILL $(pgrep $1)
}

# Warn user if package is broken (on all arches) in the current wine version. Bug report required.
w_package_broken()
{
    # FIXME: test cases for this

    bug_link="$1"
    bad_version="$2"
    good_version="$3"

    if [ -z "$bug_link" ] ; then
        w_die "Bug report link required!"
    fi

    if [ -n "$good_version" ]; then
        if ! w_wine_version_in "${bad_version},${good_version}"; then
            w_warn "This package ($W_PACKAGE) is broken in ${_wine_version_stripped}. Upgrade to >=${good_version}. See ${bug_link} for more info."
            exit 99
        fi
    elif [ -n "$bad_version" ]; then
        if ! w_wine_version_in "${bad_version}"; then
            w_warn "This package ($W_PACKAGE) is broken in ${_wine_version_stripped}. Broken since ${bad_version}. See ${bug_link} for more info."
            exit 99
        fi
    else
        w_warn "This package ($W_PACKAGE) is broken. See ${bug_link} for more info."
        exit 99
    fi
}

w_detect_mingw()
{
    # mingw builds have some (not yet all) .dll files in ${WINE}/../lib{,64}/wine
    # non-mingw have exclusively .dll.so files
    #
    # It's more portable though, to check for 'Wine (placeholder|builtin) DLL'
    # placeholder=no-mingw
    # builtin=mingw (wine-4.11+)

    # See https://github.com/Winetricks/winetricks/issues/1461
    if w_wine_version_in ,4.10 ; then
        if grep -obUa "Wine placeholder DLL" "$("$WINE" winepath -u "c:\\windows\\system32\\kernelbase.dll" 2>/dev/null)" | grep -q '64:Wine placeholder DLL'; then
            _W_no_mingw=1
        elif grep -obUa "Wine builtin DLL" "$("$WINE" winepath -u "c:\\windows\\system32\\kernelbase.dll" 2>/dev/null)" | grep -q '64:Wine builtin DLL'; then
            _W_mingw=1
        else
            w_warn "Unable to detect wine dlls, please file an issue on Github!"
        fi
    else
        # FIXME: better message here (at least, easier to grep/recognize
        echo "w_detect_mingw: mingw detection unimplemented for wine<4.11"
        _W_no_mingw=1
    fi
}

# Warn user if package is broken in the current wine version when compiled with mingw. Bug report required.
w_package_broken_mingw()
{
    # FIXME: test cases for this

    bug_link="$1"
    bad_version="$2"
    good_version="$3"

    w_detect_mingw

    if [ -z "$_W_mingw" ]; then
        # We're not using a mingw build, nothing to do:
        return
    fi

    if [ -z "$bug_link" ] ; then
        w_die "Bug report link required!"
    fi

    if [ -n "$good_version" ]; then
        if ! w_wine_version_in "${bad_version},${good_version}"; then
            w_warn "This package ($W_PACKAGE) is broken in ${_wine_version_stripped} when wine is built with mingw. Upgrade to >=${good_version} or disable mingw. See ${bug_link} for more info."
            exit 99
        else
            echo "package was broken, now fixed"
        fi
    elif [ -n "$bad_version" ]; then
        if ! w_wine_version_in "${bad_version}"; then
            w_warn "This package ($W_PACKAGE) is broken in ${_wine_version_stripped} (broken since ${bad_version} when wine is built with mingw. See ${bug_link} for more info."
            exit 99
        else
            echo "Package is broken in future versions"
        fi
    else
        w_warn "This package ($W_PACKAGE) is broken when wine is built with mingw. See ${bug_link} for more info."
        exit 99
    fi
}

# Warn user if package is broken in the current wine version when compiled without mingw. Bug report required.
w_package_broken_no_mingw()
{
    # FIXME: test cases for this

    bug_link="$1"
    bad_version="$2"
    good_version="$3"

    if [ -z "$_W_no_mingw" ]; then
        # We're using a mingw build, nothing to do:
        return
    fi

    if [ -z "$bug_link" ] ; then
        w_die "Bug report link required!"
    fi

    if [ -n "$good_version" ]; then
        if ! w_wine_version_in "${bad_version},${good_version}"; then
            w_warn "This package ($W_PACKAGE) is broken in ${_wine_version_stripped} when wine is built without mingw. Upgrade to >=${good_version}. See ${bug_link} for more info."
            exit 99
        else
            echo "package was broken, now fixed"
        fi
    elif [ -n "$bad_version" ]; then
        if ! w_wine_version_in "${bad_version}"; then
            w_warn "This package ($W_PACKAGE) is broken in ${_wine_version_stripped} (broken since ${bad_version} when wine is built without mingw. See ${bug_link} for more info."
            exit 99
        else
            echo "Package is broken in future versions"
        fi
    else
        w_warn "This package ($W_PACKAGE) is broken when wine is built without mingw. See ${bug_link} for more info."
        exit 99
    fi
}

# Warn user if package is broken on win64. Optionally provide a link to the bug report.
w_package_broken_win64()
{
    # Optional:
    bug_link="$1"

    if [ "$W_ARCH" = "win64" ] ; then
        if [ -n "$1" ] ; then
            w_die "This package ($W_PACKAGE) is broken on 64-bit Wine. Using a prefix made with WINEARCH=win32 to work around this. See: ${bug_link}"
        else
            w_die "This package ($W_PACKAGE) is broken on 64-bit Wine. Using a prefix made with WINEARCH=win32 to work around this."
        fi
    fi
}

# Some packages don't support win32, die with an appropriate message
# Returns 64 (for tests/winetricks-test)
w_package_unsupported_win32()
{
    if [ "$W_ARCH" = "win32" ] ; then
        w_warn "This package ($W_PACKAGE) does not work on a 32-bit installation. You must use a prefix made with WINEARCH=win64."
        exit 64
    fi
}


# Some packages don't support win64, die with an appropriate message
# Note: this is for packages that natively don't support win64, not packages that are broken on wine64, for that, use w_package_broken_win64()
# Returns 32 (for tests/winetricks-test)
w_package_unsupported_win64()
{
    if [ "$W_ARCH" = "win64" ] ; then
        case $LANG in
            pl*) w_warn "Ten pakiet ($W_PACKAGE) nie działa z 64-bitową instalacją. Musisz użyć prefiksu utworzonego z WINEARCH=win32." ;;
            ru*) w_warn "Данный пакет не работает в 64-битном окружении. Используйте префикс, созданный с помощью WINEARCH=win32." ;;
            *) w_warn "This package ($W_PACKAGE) does not work on a 64-bit installation. You must use a prefix made with WINEARCH=win32." ;;
        esac
        exit 32
    fi
}

# For packages that are not well tested or have some known issues on win64, but aren't broken
w_package_warn_win64()
{
    if [ "$W_ARCH" = "win64" ] ; then
        case $LANG in
            pl*) w_warn "Ten pakiet ($W_PACKAGE) może nie działać poprawnie z 64-bitową instalacją. Prefiks 32-bitowy może działać lepiej." ;;
            ru*) w_warn "Данный пакет может работать не полностью в 64-битном окружении. 32-битные префиксы могут работать лучше." ;;
            *) w_warn "This package ($W_PACKAGE) may not fully work on a 64-bit installation. 32-bit prefixes may work better." ;;
        esac
    fi
}

### w_try and w_try wrappers ###

# Execute with error checking
# Put this in front of any command that might fail
w_try()
{
    # "VAR=foo w_try cmd" fails to put VAR in the environment
    # with some versions of bash if w_try is a shell function?!
    # This is a problem when trying to pass environment variables to e.g. wine.
    # Adding an explicit export here works around it, so add any we use.
    export WINEDLLOVERRIDES
    # If $WINETRICKS_SUPER_QUIET is set, make w_try quiet
    if [ -z "$WINETRICKS_SUPER_QUIET" ]; then
        printf '%s\n' "Executing $*"
    fi

    # On Vista, we need to jump through a few hoops to run commands in Cygwin.
    # First, .exe's need to have the executable bit set.
    # Second, only cmd can run setup programs (presumably for security).
    # If $1 ends in .exe, we know we're running on real Windows, otherwise
    # $1 would be 'wine'.
    case "$1" in
        *.exe)
            chmod +x "$1" || true # don't care if it fails
            cmd /c "$@"
            ;;
        *)
            "$@"
            ;;
    esac
    status=$?

    en_ms_5="exit status ${status} - user selected 'Cancel'"
    en_ms_105="exit status ${status} - normal, user selected 'restart now'"
    en_ms_194="exit status ${status} - normal, user selected 'restart later'"

    en_abort="Note: command $* returned status ${status}. Aborting."
    pl_abort="Informacja: poelcenie $* zwróciło status ${status}. Przerywam."
    ru_abort="Важно: команда $* вернула статус ${status}. Прерывание."

    if [ -n "${_w_ms_installer}" ]; then
        case ${status} in
            # Nonfatal
            0) ;;
            105) echo "${en_ms_105}" ;;
            194) echo "${en_ms_194}" ;;

            # Fatal
            5) w_die "${en_ms_5}" ;;
            *) w_die "${en_abort}" ;;
        esac
    else
        case ${status} in
            0) ;;
            *)
                case ${LANG} in
                    pl*) w_die "${pl_abort}" ;;
                    ru*) w_die "${ru_abort}" ;;
                    *) w_die "${en_abort}" ;;
                esac
                ;;
        esac
    fi
}

# For some MS installers that have special exit codes:
w_try_ms_installer()
{
    _w_ms_installer=true
    w_try "$@"
    unset _w_ms_installer
}

w_try_7z()
{
    # $1 - directory to extract to
    # $2 - file to extract
    # $3 .. $n - files to extract from the archive

    destdir="$1"
    filename="$2"
    shift 2

    # Not always installed, use Windows 7-Zip as a fallback:
    if [ -z "$WINETRICKS_FORCE_WIN_7Z" ] && [ -x "$(command -v 7z 2>/dev/null)" ] ; then
        w_try 7z x "$filename" -o"$destdir" "$@"
    else
        w_warn "Cannot find 7z. Using Windows 7-Zip instead. (You can avoid this by installing 7z, e.g. 'sudo apt-get install p7zip-full' or 'sudo yum install p7zip-plugins')."
        WINETRICKS_OPT_SHAREDPREFIX=1 w_call 7zip

        # w_call above will wipe $W_TMP; if that's the CWD, things will break. So forcefully reset the directory:
        w_try_cd "$PWD"

        # errors out if there is a space between -o and path
        w_try "$WINE" "$W_PROGRAMS_X86_WIN\\7-Zip\\7z.exe" x "$(w_pathconv -w "$filename")" -o"$(w_pathconv -w "$destdir")" "$@"
    fi
}

w_try_ar()
{
    # $1 - ar file (.deb) to extract (keeping internal paths, in cwd)
    # $2 - file to extract (optional)

    # Not always installed, use Windows 7-zip as a fallback:
    if [ -z "$WINETRICKS_FORCE_WIN_7Z" ] && [ -x "$(command -v ar 2>/dev/null)" ]; then
        w_try ar x "$@"
    else
        w_warn "Cannot find ar. Using Windows 7-zip instead. (You can avoid this by installing binutils, e.g. 'sudo apt-get install binutils' or 'sudo yum install binutils')."
        WINETRICKS_OPT_SHAREDPREFIX=1 w_call 7zip

        # w_call above will wipe $W_TMP; if that's the CWD, things will break. So forcefully reset the directory:
        w_try_cd "$PWD"

        # -t* prevents 7-zip from decompressing .tar.xz to .tar, see
        # https://sourceforge.net/p/sevenzip/discussion/45798/thread/8cd16946/?limit=25
        w_try "$WINE" "$W_PROGRAMS_X86_WIN\\7-Zip\\7z.exe" -t* x "$(w_pathconv -w "$1")"
    fi
}

w_try_cabextract()
{
    # Not always installed, but shouldn't be fatal unless it's being used
    if test ! -x "$(command -v cabextract 2>/dev/null)"; then
        w_die "Cannot find cabextract.  Please install it (e.g. 'sudo apt-get install cabextract' or 'sudo yum install cabextract')."
    fi

    w_try cabextract -q "$@"
}

w_try_cd()
{
    w_try cd "$@"
}

# Copy font files matching a glob pattern from source directory to destination directory.
# Also remove any file in the destination directory that has the same name as
# any of the files that we're trying to copy, but with different case letters.
# Note: it converts font file names to lower case to avoid inconsistencies due to paths
#       being case-insensitive under Wine.
w_try_cp_font_files()
{
    # $1 - source directory
    # $2 - destination directory
    # $3 - optional font file glob pattern (default: "*.ttf")

    _W_src_dir="$1"
    _W_dest_dir="$2"
    _W_pattern="$3"
    shift 2

    if test ! -d "$_W_src_dir"; then
        w_die "bug: missing source dir"
    fi

    if test ! -d "$_W_dest_dir"; then
        w_die "bug: missing destination dir"
    fi

    if test -z "$_W_pattern"; then
        _W_pattern="*.ttf"
    fi

# POSIX sh doesn't have a good way to handle this, but putting into a separate script
# and running with sh avoids it.
#
# See https://github.com/Winetricks/winetricks/issues/995 for details

cat > "$WINETRICKS_WORKDIR/cp_font_files.sh" <<_EOF_
#!/bin/sh
    _W_src_file="\$@"

    # Extract the file name and lower case it
    _W_file_name="\$(basename "\$_W_src_file" | tr "[:upper:]" "[:lower:]")"

    # Remove any existing font files that might have the same name, but with different case characters
    find "$_W_dest_dir" -maxdepth 1 -type f -iname "\$_W_file_name" -exec rm '{}' ';'

    # FIXME: w_try() isn't available, need some better error handling:
    cp -f "\$_W_src_file" "$_W_dest_dir/\$_W_file_name"
_EOF_

    # Use -exec "sh .." to avoid issues with noexec
    # Gross quoting is to avoid SC2156
    find "$_W_src_dir" -maxdepth 1 -type f -iname "$_W_pattern" -exec sh -c 'sh '"$WINETRICKS_WORKDIR/cp_font_files.sh"' "$1"' _ {} \;

    # Wait for Wine to add the new font to the registry under HKCU\Software\Wine\Fonts\Cache
    
    #w_wineserver -w

    unset _W_dest_dir
}

w_try_msiexec64()
{
    if test "$W_ARCH" != "win64"; then
        w_die "bug: 64-bit msiexec called from a $W_ARCH prefix."
    fi

    # shellcheck disable=SC2086
    w_try "$WINE" start /wait "$W_SYSTEM64_DLLS_WIN32/msiexec.exe" $W_UNATTENDED_SLASH_Q "$@"
}

w_try_regedit()
{
    # If on wow64, run under both wine and wine64 (otherwise they only go in the 32-bit registry afaict)

    # shellcheck disable=SC2086
    if [ "$W_ARCH" = "win32" ]; then
        w_try_regedit32 "$@"
    elif [ "$W_ARCH" = "win64" ]; then
        w_try_regedit32 "$@"
        w_try_regedit64 "$@"
    fi
}

# fixme: cleanup. For wow64 registries, some/all entries need to be duplicated.
# Not sure of the best way yet, but thinking running wine/wine64 regedit for each?
w_try_regedit32()
{
    # on windows, doesn't work without cmd /c
    case "$W_PLATFORM" in
        windows_cmd|wine_cmd) cmdc="cmd /c";;
        *) unset cmdc ;;
    esac

    # shellcheck disable=SC2086
    w_try "$WINE_MULTI" $cmdc regedit $W_UNATTENDED_SLASH_S "$@"
}

w_try_regedit64()
{
    # on windows, doesn't work without cmd /c
    case "$W_PLATFORM" in
        windows_cmd|wine_cmd) cmdc="cmd /c";;
        *) unset cmdc ;;
    esac

    # shellcheck disable=SC2086
    w_try "$WINE64" $cmdc regedit $W_UNATTENDED_SLASH_S "$@"
}

w_try_regsvr()
{
    # shellcheck disable=SC2086
    w_try "$WINE" regsvr32 $W_UNATTENDED_SLASH_S "$@"
}

w_try_regsvr64()
{
    # shellcheck disable=SC2086
    w_try "$WINE64" regsvr32 $W_UNATTENDED_SLASH_S "$@"
}

w_try_unrar()
{
    # $1 - zipfile to extract (keeping internal paths, in cwd)

    # Not always installed, use Windows 7-Zip as a fallback:
    if [ -z "$WINETRICKS_FORCE_WIN_7Z" ] && [ -x "$(command -v unrar 2>/dev/null)" ]; then
        w_try unrar x "$@"
    else
        w_warn "Cannot find unrar. Using Windows 7-Zip instead. (You can avoid this by installing unrar, e.g. 'sudo apt-get install unrar' or 'sudo yum install unrar')."
        WINETRICKS_OPT_SHAREDPREFIX=1 w_call 7zip

        # w_call above will wipe $W_TMP; if that's the CWD, things will break. So forcefully reset the directory:
        w_try_cd "$PWD"

        w_try "$WINE" "$W_PROGRAMS_X86_WIN\\7-Zip\\7z.exe" x "$(w_pathconv -w "$1")"
    fi
}

w_try_unzip()
{
    # $1 - directory to extract to
    # $2 - zipfile to extract
    # $3 .. $n - files to extract from the archive

    destdir="$1"
    zipfile="$2"
    shift 2

    # Not always installed, use Windows 7-Zip as a fallback:
    if [ -z "$WINETRICKS_FORCE_WIN_7Z" ] && [ -x "$(command -v unzip 2>/dev/null)" ]; then
        # FreeBSD ships unzip, but it doesn't support self-compressed executables
        # If it fails, fall back to 7-Zip:
        unzip -o -q -d"$destdir" "$zipfile" "$@"
        ret=$?
        case $ret in
            0) return ;;
            1|*) w_warn "Unzip failed, trying Windows 7-Zip instead." ;;
        esac
    else
        w_warn "Cannot find unzip. Using Windows 7-Zip instead. (You can avoid this by installing unzip, e.g. 'sudo apt-get install unzip' or 'sudo yum install unzip')."
    fi

    WINETRICKS_OPT_SHAREDPREFIX=1 w_call 7zip

    # w_call above will wipe $W_TMP; if that's the CWD, things will break. So forcefully reset the directory:
    w_try_cd "$PWD"

    # errors out if there is a space between -o and path
    w_try "$WINE" "$W_PROGRAMS_X86_WIN\\7-Zip\\7z.exe" x "$(w_pathconv -w "$zipfile")" -o"$(w_pathconv -w "$destdir")" "$@"
}

### End of w_try ###

w_read_key()
{
    if test ! "$W_OPT_UNATTENDED"; then
        W_KEY=dummy_to_make_autohotkey_happy
        return 0
    fi

    mkdir -p "$W_CACHE/$W_PACKAGE"

    # backwards compatible location
    # Auth doesn't belong in cache, since restoring it requires user input
    _W_keyfile="$W_CACHE/$W_PACKAGE/key.txt"
    if ! test -f "$_W_keyfile"; then
        _W_keyfile="$WINETRICKS_AUTH/$W_PACKAGE/key.txt"
    fi
    if ! test -f "$_W_keyfile"; then
        # read key from user
        case $LANG in
            da*) _W_keymsg="Angiv venligst registrerings-nøglen for pakken '$W_PACKAGE'"
                _W_nokeymsg="Ingen nøgle angivet"
                ;;
            de*) _W_keymsg="Bitte einen Key für Paket '$W_PACKAGE' eingeben"
                _W_nokeymsg="Keinen Key eingegeben?"
                ;;
            pl*) _W_keymsg="Proszę podać klucz dla programu '$W_PACKAGE'"
                _W_nokeymsg="Nie podano klucza"
                ;;
            ru*) _W_keymsg="Пожалуйста, введите ключ для приложения '$W_PACKAGE'"
                _W_nokeymsg="Ключ не введён"
                ;;
            uk*) _W_keymsg="Будь ласка, введіть ключ для додатка '$W_PACKAGE'"
                _W_nokeymsg="Ключ не надано"
                ;;
            zh_CN*)  _W_keymsg="按任意键为 '$W_PACKAGE'"
                _W_nokeymsg="No key given"
                ;;
            zh_TW*|zh_HK*)  _W_keymsg="按任意鍵為 '$W_PACKAGE'"
                _W_nokeymsg="No key given"
                ;;
            *)  _W_keymsg="Please enter the key for app '$W_PACKAGE'"
                _W_nokeymsg="No key given"
                ;;
        esac

        case $WINETRICKS_GUI in
            *zenity) W_KEY=$(zenity --entry --text "$_W_keymsg") ;;
            *kdialog) W_KEY=$(kdialog --inputbox "$_W_keymsg") ;;
            *xmessage) w_die "sorry, can't read key from GUI with xmessage" ;;
            none) printf %s "$_W_keymsg": ; read -r W_KEY ;;
        esac

        if test "$W_KEY" = ""; then
            w_die "$_W_nokeymsg"
        fi
        echo "$W_KEY" > "$_W_keyfile"
    fi
    W_RAW_KEY=$(cat "$_W_keyfile")
    W_KEY=$(echo "$W_RAW_KEY" | tr -d '[:blank:][=-=]')
    unset _W_keyfile _W_keymsg _W_nokeymsg
}

w_verify_cabextract_available()
{
    # If verb_a requires verb_b, then verba will fail when the dependency for verb_b is installed
    # This should be called by verb_a, to give a proper warning

    w_try_cabextract -q -v >/dev/null 2>&1
}

# Convert a Windows path to a Unix path quickly.
# $1 is an absolute Windows path starting with c:\ or C:/
# with no funny business, so we can use the simplest possible
# algorithm.
winetricks_wintounix()
{
    _W_winp_="$1"
    # Remove drive letter and colon
    _W_winp="${_W_winp_#??}"
    # Prepend the location of drive c
    printf %s "$WINEPREFIX"/dosdevices/c:
    # Change backslashes to slashes
    echo "$_W_winp" | sed 's,\\,/,g'
}

# Convert between Unix path and Windows path
# Usage is lowest common denominator of cygpath/winepath
# so -u to convert to Unix, and -w to convert to Windows
w_pathconv()
{
    case "$W_PLATFORM" in
        windows_cmd)
            # for some reason, cygpath turns some spaces into newlines?!
            cygpath "$@" | tr '\012' '\040' | sed 's/ $//'
            ;;
        *)
            case "$@" in
                -u?c:\\*|-u?C:\\*|-u?c:/*|-u?C:/*) winetricks_wintounix "$2" ;;
                *) winetricks_early_wine winepath "$@" ;;
            esac
        ;;
    esac
}

# Expand an environment variable and print it to stdout
w_expand_env()
{
    winetricks_early_wine_arch cmd.exe /c echo "%$1%"
}

# Get the latest tagged release from github.com API
w_get_github_latest_release()
{
    # FIXME: can we get releases that aren't on master branch?
    org="$1"
    repo="$2"

    WINETRICKS_SUPER_QUIET=1 w_download_to "${W_TMP_EARLY}" "https://api.github.com/repos/${org}/${repo}/releases/latest" "" "release.json" >/dev/null 2>&1

    # aria2c condenses the json (https://github.com/aria2/aria2/issues/1389)
    # but curl/wget don't, so handle both cases:
    json_length="$(wc -l "${W_TMP_EARLY}/release.json")"
    case "$json_length" in
        0*) latest_version="$(sed -e "s/\",\"/|/g" "${W_TMP_EARLY}/release.json" | tr '|' '\n' | grep tag_name | sed 's@.*"@@')";;
        *) latest_version="$(grep -w tag_name "${W_TMP_EARLY}/release.json" | cut -d '"' -f 4)";;
    esac

    echo "$latest_version"
}

# Get the latest tagged prerelease from github.com API
w_get_github_latest_prerelease()
{
    # FIXME: can we get releases that aren't on master branch?
    org="$1"
    repo="$2"

    WINETRICKS_SUPER_QUIET=1 w_download_to "${W_TMP_EARLY}" "https://api.github.com/repos/${org}/${repo}/releases" "" "release.json" >/dev/null 2>&1

    # aria2c condenses the json (https://github.com/aria2/aria2/issues/1389)
    # but curl/wget don't, so handle both cases:
    json_length="$(wc -l "${W_TMP_EARLY}/release.json")"
    case "$json_length" in
        0*) latest_version="$(sed -e "s/\",\"/|/g" "${W_TMP_EARLY}/release.json" | tr '|' '\n' | grep tag_name -m 1 | sed 's@.*"@@')";;
        *) latest_version="$(grep -m 1 -w tag_name "${W_TMP_EARLY}/release.json" | cut -d '"' -f 4)";;
    esac

    echo "$latest_version"
}

# get sha256sum string and set $_W_gotsha256sum to it
w_get_sha256sum()
{
    _W_sha256_file="$1"

    # See https://github.com/Winetricks/winetricks/issues/645
    # User is running winetricks from /dev/stdin
    if [ -f "$_W_sha256_file" ] || [ -h "$_W_sha256_file" ] ; then
        _W_gotsha256sum=$($WINETRICKS_SHA256SUM < "$_W_sha256_file" | sed 's/(stdin)= //;s/ .*//')
    else
        w_warn "$_W_sha256_file is not a regular file, not checking sha256sum"
        return
    fi
}

w_get_shatype() {
    _W_sum="$1"

    # tr -d " " is for FreeBSD/OS X/Solaris return a leading space:
    # See https://stackoverflow.com/questions/30927590/wc-on-osx-return-includes-spaces/30927885#30927885
    _W_sum_length="$(echo "$_W_sum" | tr -d "\\n" | wc -c | tr -d " ")"
    case "$_W_sum_length" in
        0) _W_shatype="none" ;;
        64) _W_shatype="sha256" ;;
        # 128) sha512..
        *) w_die "unsupported shasum..bug" ;;
    esac
}

# verify a sha256sum
w_verify_sha256sum()
{
    _W_vs_wantsum=$1
    _W_vs_file=$2

    w_get_sha256sum "$_W_vs_file"
    if [ "$_W_gotsha256sum"x != "$_W_vs_wantsum"x ] ; then
        case $LANG in
            pl*) w_die "Niezgodność sumy sha256sum! Zmień nazwę $_W_vs_file i spróbuj ponownie." ;;
            ru*) w_die "Контрольная сумма sha256sum не совпадает! Переименуйте файл $_W_vs_file и попробуйте еще раз." ;;
            *) w_die "sha256sum mismatch! Rename $_W_vs_file and try again." ;;
        esac
    fi
    unset _W_vs_wantsum _W_vs_file _W_gotsha256sum
}

# verify any kind of shasum (that winetricks supports ;) ):
w_verify_shasum()
{
    _W_vs_wantsum="$1"
    _W_vs_file="$2"

    w_get_shatype "$_W_vs_wantsum"

    case "$_W_shatype" in
        none) w_warn "No checksum provided, not verifying" ;;
        sha256) w_verify_sha256sum "$_W_sum" "$_W_vs_file" ;;
        # 128) sha512..
        *) w_die "unsupported shasum..bug" ;;
    esac
}

# wget outputs progress messages that look like this:
#      0K .......... .......... .......... .......... ..........  0%  823K 40s
# This function replaces each such line with the pair of lines
# 0%
# # Downloading... 823K (40s)
# It uses minimal buffering, so each line is output immediately
# and the user can watch progress as it happens.

# wrapper around wineserver, to let users know that it will wait indefinitely/kill stuff
w_wineserver()
{

    case "$@" in
        *-k) w_warn "Running $WINESERVER -k. This will kill all running wine processes in prefix=$WINEPREFIX";;
        *-w) w_warn "Running $WINESERVER -w. This will hang until all wine processes in prefix=$WINEPREFIX terminate";;
        *)   w_warn "Invoking wineserver with '$*'";;
    esac
     shellcheck disable=SC2068
    "$WINESERVER" $@
}

winetricks_parse_wget_progress()
{
    # Parse a percentage, a size, and a time into $1, $2 and $3
    # then use them to create the output line.
    case $LANG in
        pl*) perl -p -e \
            '$| = 1; s/^.* +([0-9]+%) +([0-9,.]+[GMKB]) +([0-9hms,.]+).*$/\1\n# Pobieranie… \2 (\3)/' ;;
        ru*) perl -p -e \
            '$| = 1; s/^.* +([0-9]+%) +([0-9,.]+[GMKB]) +([0-9hms,.]+).*$/\1\n# Загрузка... \2 (\3)/' ;;
        *) perl -p -e \
            '$| = 1; s/^.* +([0-9]+%) +([0-9,.]+[GMKB]) +([0-9hms,.]+).*$/\1\n# Downloading... \2 (\3)/' ;;
    esac
}

# Execute wget, and if in GUI mode, also show a graphical progress bar
winetricks_wget_progress()
{
    case $WINETRICKS_GUI in
        zenity)
            # Use a subshell so if the user clicks 'Cancel',
            # the --auto-kill kills the subshell, not the current shell
            (
                ${torify} wget "$@" 2>&1 |
                winetricks_parse_wget_progress | \
                $WINETRICKS_GUI --progress --width 400 --title="$_W_file" --auto-kill --auto-close
            )
            err=$?
            if test $err -gt 128; then
                # 129 is 'killed by SIGHUP'
                # Sadly, --auto-kill only applies to parent process,
                # which was the subshell, not all the elements of the pipeline...
                # have to go find and kill the wget.
                # If we ran wget in the background, we could kill it more directly, perhaps...
                if pid=$(pgrep -f ."$_W_file"); then
                    echo User aborted download, killing wget
                    # shellcheck disable=SC2086
                    kill $pid
                fi
            fi
            return $err
            ;;
        *) ${torify} wget "$@" ;;
    esac
}

w_dotnet_verify()
{
    case "$1" in
        dotnet11) version="1.1" ;;
        dotnet11sp1) version="1.1 SP1" ;;
        dotnet20) version="2.0" ;;
        dotnet20sp1) version="2.0 SP1" ;;
        dotnet20sp2) version="2.0 SP2" ;;
        dotnet30) version="3.0" ;;
        dotnet30sp1) version="3.0 SP1" ;;
        dotnet35) version="3.5" ;;
        dotnet35sp1) version="3.5 SP1" ;;
        dotnet40) version="4 Client" ;;
        dotnet45) version="4.5" ;;
        dotnet452) version="4.5.2" ;;
        dotnet46) version="4.6" ;;
        dotnet461) version="4.6.1" ;;
        dotnet462) version="4.6.2" ;;
        dotnet471) version="4.7.1" ;;
        dotnet472) version="4.7.2" ;;
        dotnet48) version="4.8" ;;
        *) echo error ; exit 1 ;;
    esac

    w_call dotnet_verifier

    # FIXME: The logfile may be useful somewhere (or at least print the location)

    # for 'run, netfx_setupverifier.exe /q:a /c:"setupverifier2.exe"' line
    # shellcheck disable=SC2140
    w_ahk_do "
        SetTitleMatchMode, 2
        ; FIXME; this only works the first time? Check if it's already verified somehow..

        run, netfx_setupverifier.exe /q:a /c:"setupverifier2.exe"
        winwait, Verification Utility
        ControlClick, Button1
        Control, ChooseString, NET Framework $version, ComboBox1
        ControlClick, Button1 ; Verify
        loop, 60
        {
            sleep 1000
            process, exist, setupverifier2.exe
            dn_pid=%ErrorLevel%
            if dn_pid = 0
            {
                break
            }
            ifWinExist, Verification Utility, Product verification failed
            {
                process, close, setupverifier2.exe
                exit 1
            }
            ifWinExist, Verification Utility, Product verification succeeded
            {
                process, close, setupverifier2.exe
                break
            }
        }
    "
    dn_status="$?"
    w_info ".Net Verifier returned $dn_status"
}

# Checks if the user can run the self-update/rollback commands
winetricks_check_update_availability()
{
    # Prevents the development file overwrite:
    if test -d "../.git"; then
        w_warn "You're running in a dev environment. Please make a copy of the file before running this command."
        exit
    fi

    # Checks read/write permissions on update directories
    if ! { test -r "$0" && test -w "$0" && test -w "${0%/*}" && test -x "${0%/*}"; }; then
        w_warn "You don't have the proper permissions to run this command. Try again with sudo or as root."
        exit
    fi
}

winetricks_selfupdate()
{
    winetricks_check_update_availability

    _W_filename="${0##*/}"
    _W_rollback_file="${0}.bak"
    _W_update_file="${0}.update"

    _W_tmpdir=${TMPDIR:-/tmp}
    _W_tmpdir="$(mktemp -d "$_W_tmpdir/$_W_filename.XXXXXXXX")"

    w_download_to "$_W_tmpdir" https://gitee.com/JackLee02/vekGame/raw/master/winetricks "" "$_W_filename"

    # 2016/10/26: now file is uncompressed? Handle both cases:
    update_file_type="$(file "$_W_tmpdir/$_W_filename")"
    case "$update_file_type" in
        *"Bourne-Again shell script"*)
            #echo "already decompressed!"
            w_try mv "$_W_tmpdir/$_W_filename" "${_W_update_file}"
            ;;
        *"gzip compressed data"*)
            w_try mv "$_W_tmpdir/$_W_filename" "${_W_update_file}.gz"
            w_try gunzip "${_W_update_file}.gz"
            ;;
        *)
            echo "Unknown file type: $update_file_type"
            exit 1
            ;;
    esac

    w_try rmdir "$_W_tmpdir"

    w_try cp "$0" "$_W_rollback_file"
    w_try chmod -x "$_W_rollback_file"

    w_try mv "$_W_update_file" "$0"
    w_try chmod +x "$0"

    w_warn "Update finished! The current version is $($0 -V). Use 'winetricks --update-rollback' to return to the previous version."

    exit
}

winetricks_selfupdate_rollback()
{
    winetricks_check_update_availability

    _W_rollback_file="${0}.bak"

    if test -f "$_W_rollback_file"; then
        w_try mv "$_W_rollback_file" "$0"
        w_try chmod +x "$0"
        w_warn "Rollback finished! The current version is $($0 -V)."
    else
        w_warn "Nothing to rollback."
    fi
    exit;
}

# Download a file
# Usage: w_download_to (packagename|path to download file) url [shasum [filename [cookie jar]]]
# Caches downloads in winetrickscache/$packagename
w_download_to()
{
    winetricks_download_setup

    _W_packagename="$1" # or path to download file to
    _W_url="$2"
    _W_sum="$3"
    _W_file="$4"
    _W_cookiejar="$5"

    case $_W_packagename in
        .) w_die "bug: please do not download packages to top of cache" ;;
    esac

    if echo "$_W_url" | grep ' ' ; then
        w_die "bug: please use %20 instead of literal spaces in urls, curl rejects spaces, and they make life harder for linkcheck.sh"
    fi
    if [ "$_W_file"x = ""x ] ; then
        _W_file=$(basename "$_W_url")
    fi

    w_get_shatype "$_W_sum"

    if echo "${_W_packagename}" | grep -q -e '\/-' -e '^-'; then
            w_die "Invalid path ${_W_packagename} given"
    else
        if ! echo "${_W_packagename}" | grep -q '^/' ; then
            _W_cache="$W_CACHE/$_W_packagename"
        else
            _W_cache="$_W_packagename"
        fi
    fi

    if test ! -d "$_W_cache" ; then
        w_try mkdir -p "$_W_cache"
    fi

    # Try download twice
    checksum_ok=""
    tries=0
    # Set olddir before entering the loop, otherwise second try will overwrite
    _W_dl_olddir=$(pwd)
    while test $tries -lt 2 ; do
        # Warn on a second try
        test "$tries" -eq 1 && winetricks_dl_warning
        tries=$((tries + 1))

        if test -s "$_W_cache/$_W_file" ; then
            if test "$_W_sum" ; then
                if test $tries = 1 ; then
                    # The cache was full.  If the file is larger than 500 MB,
                    # don't checksum it, that just annoys the user.
                    # shellcheck disable=SC2046
                    if test $(du -k "$_W_cache/$_W_file" | cut -f1) -gt 500000 ; then
                        checksum_ok=1
                        break
                    fi
                fi
                # If checksum matches, declare success and exit loop
                case "$_W_shatype" in
                    none)
                        w_warn "No checksum provided, not verifying"
                        ;;
                    sha256)
                        w_get_sha256sum "$_W_cache/$_W_file"
                        if [ "$_W_gotsha256sum"x = "$_W_sum"x ] ; then
                            checksum_ok=1
                            break
                        fi
                        ;;
                esac

                if test ! "$WINETRICKS_CONTINUE_DOWNLOAD" ; then
                    case $LANG in
                        pl*) w_warn "Niezgodność sum kontrolnych dla $_W_cache/$_W_file, pobieram ponownie" ;;
                        ru*) w_warn "Контрольная сумма файла $_W_cache/$_W_file не совпадает, попытка повторной загрузки" ;;
                        *) w_warn "Checksum for $_W_cache/$_W_file did not match, retrying download" ;;
                    esac
                    mv -f "$_W_cache/$_W_file" "$_W_cache/$_W_file".bak
                fi
            else
                # file exists, no checksum known, declare success and exit loop
                break
            fi
        elif test -f "$_W_cache/$_W_file" ; then
            # zero-length file, just delete before retrying
            rm "$_W_cache/$_W_file"
        fi

        w_try_cd "$_W_cache"
        # Mac folks tend to have curl rather than wget
        # On Mac, 'which' doesn't return good exit status
        echo "Downloading $_W_url to $_W_cache"

        # For sites that prefer Mozilla in the user-agent header, set W_BROWSERAGENT=1
        case "$W_BROWSERAGENT" in
            1) _W_agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36" ;;
            *) _W_agent="" ;;
        esac

        if [ "${WINETRICKS_DOWNLOADER}" = "aria2c" ] ; then
            # Note: aria2c wants = for most options or silently fails

            # (Slightly fancy) aria2c support
            # See https://github.com/Winetricks/winetricks/issues/612
            # --daemon=false --enable-rpc=false to ensure aria2c doesnt go into the background after starting
            #   and prevent any attempts to rebind on the RPC interface specified in someone's config.
            # --input-file='' if the user config has a input-file specified then aria2 will read it and
            #   attempt to download everything in that input file again.
            # --save-session='' if the user has specified save-session in their config, their session will be
            #   ovewritten by the new aria2 process

            # shellcheck disable=SC2086
            $torify aria2c \
                $aria2c_torify_opts \
                --connect-timeout="${WINETRICKS_DOWNLOADER_TIMEOUT}" \
                --continue \
                --daemon=false \
                --dir="$_W_cache" \
                --enable-rpc=false \
                --input-file='' \
                --max-connection-per-server=5 \
                --max-tries="$WINETRICKS_DOWNLOADER_RETRIES" \
                --out="$_W_file" \
                --save-session='' \
                --stream-piece-selector=geom \
                "$_W_url"
        elif [ "${WINETRICKS_DOWNLOADER}" = "wget" ] ; then
            # Use -nd to insulate ourselves from people who set -x in WGETRC
            # [*] --retry-connrefused works around the broken sf.net mirroring
            # system when downloading corefonts
            # [*] --read-timeout is useful on the adobe server that doesn't
            # close the connection unless you tell it to (control-C or closing
            # the socket)

            # shellcheck disable=SC2086
            
            winetricks_wget_progress \
                -O "$_W_file" \
                -nd \
                -c\
                --read-timeout 300 \
                --retry-connrefused \
                --timeout "${WINETRICKS_DOWNLOADER_TIMEOUT}" \
                --tries "$WINETRICKS_DOWNLOADER_RETRIES" \
                ${_W_cookiejar:+--load-cookies "$_W_cookiejar"} \
                ${_W_agent:+--user-agent="$_W_agent"} \
                "$_W_url"
        elif [ "${WINETRICKS_DOWNLOADER}" = "curl" ] ; then
            # Note: curl does not accept '=' when passing options
            # curl doesn't get filename from the location given by the server!
            # fortunately, we know it

            # shellcheck disable=SC2086
            $torify curl \
                --connect-timeout "${WINETRICKS_DOWNLOADER_TIMEOUT}" \
                -L \
                -o "$_W_file" \
                -C - \
                --retry "$WINETRICKS_DOWNLOADER_RETRIES" \
                ${_W_cookiejar:+--cookie "$_W_cookiejar"} \
                ${_W_agent:+--user-agent "$_W_agent"} \
                "$_W_url"
        elif [ "${WINETRICKS_DOWNLOADER}" = "fetch" ] ; then
            # Note: fetch does not support configurable retry count

            # shellcheck disable=SC2086
            $torify fetch \
                -T "${WINETRICKS_DOWNLOADER_TIMEOUT}" \
                -o "$_W_file" \
                ${_W_agent:+--user-agent="$_W_agent"} \
                "$_W_url"
        else
            w_die "Here be dragons"
        fi

        if test $? = 0; then
            # Need to decompress .exe's that are compressed, else Cygwin fails
            # Also affects ttf files on github
            # FIXME: gzip hack below may no longer be needed, but need to investigate before removing
            _W_filetype=$(command -v file 2>/dev/null)
            case $_W_filetype-$_W_file in
                /*-*.exe|/*-*.ttf|/*-*.zip)
                    case $(file "$_W_file") in
                        *:*gzip*) mv "$_W_file" "$_W_file.gz"; gunzip < "$_W_file.gz" > "$_W_file";;
                    esac
            esac

            # On Cygwin, .exe's must be marked +x
            case "$_W_file" in
                *.exe) chmod +x "$_W_file" ;;
            esac

            w_try_cd "$_W_dl_olddir"
            unset _W_dl_olddir

            # downloaded successfully, exit from loop
            break
        elif test $tries = 2; then
            test -f "$_W_file" && rm "$_W_file"
            w_die "Downloading $_W_url failed"
        fi
        # Download from the Wayback Machine on second try
        _W_url="$_W_url"
    done

    if test "$_W_sum" && test ! "$checksum_ok"; then
        w_verify_shasum "$_W_sum" "$_W_cache/$_W_file"
    fi
}

# Open a folder for the user in the specified directory
# Usage: w_open_folder directory
w_open_folder()
{
    for _W_cmd in xdg-open open cygstart true ; do
        _W_cmdpath=$(command -v $_W_cmd)
        if test -n "$_W_cmdpath" ; then
            break
        fi
    done
    $_W_cmd "$1" &
    unset _W_cmd _W_cmdpath
}

# Open a web browser for the user to the given page
# Usage: w_open_webpage url
w_open_webpage()
{
    # See https://www.dwheeler.com/essays/open-files-urls.html
    for _W_cmd in xdg-open sdtwebclient cygstart open firefox true ; do
        _W_cmdpath=$(command -v $_W_cmd)
        if test -n "$_W_cmdpath" ; then
            break
        fi
    done
    $_W_cmd "$1" &
    unset _W_cmd _W_cmdpath
}

# Download a file
# Usage: w_download url [shasum [filename [cookie jar]]]
# Caches downloads in winetrickscache/$W_PACKAGE
w_download()
{
    w_download_to "$W_PACKAGE" "$@"
}

# Download one or more files via BitTorrent
# Usage: w_download_torrent [foo.torrent]
# Caches downloads in $W_CACHE/$W_PACKAGE, torrent files are assumed to be there
# If no foo.torrent is given, will add ALL .torrent files in $W_CACHE/$W_PACKAGE
w_download_torrent()
{
    # FIXME: figure out how to extract the filename from the .torrent file
    # so callers don't need to check if the files are already downloaded.

    w_call utorrent

    UT_WINPATH="$W_CACHE_WIN\\$W_PACKAGE"
    w_try_cd "$W_CACHE/$W_PACKAGE"

    if [ "$2"x != ""x ] ; then # foo.torrent parameter supplied
        w_try "$WINE" utorrent "/DIRECTORY" "$UT_WINPATH" "$UT_WINPATH\\$2" &
    else # grab all torrents
        for torrent in *.torrent ; do
            w_try "$WINE" utorrent "/DIRECTORY" "$UT_WINPATH" "$UT_WINPATH\\$torrent" &
        done
    fi

    # Start uTorrent, have it wait until all downloads are finished
    w_ahk_do "
        SetTitleMatchMode, 2
        winwait, Torrent
        Loop
        {
            sleep 6000
            ifwinexist, Torrent, default
            {
                ;should uTorrent be the default torrent app?
                controlclick, Button1, Torrent, default  ; yes
                continue
            }
            ifwinexist, Torrent, already
            {
                ;torrent already registered, fine
                controlclick, Button1, Torrent, default  ; yes
                continue
            }
            ifwinexist, Torrent, Bandwidth
            {
                ;Cancels bandwidth test on first run of uTorrent
                controlclick, Button5, Torrent, Bandwidth
                continue
            }
            ifwinexist, Torrent, version
            {
                ;Decline upgrade to newer version
                controlclick, Button3, Torrent, version
                controlclick, Button2, Torrent, version
                continue
            }
            break
        }
        ;Sets parameter to close uTorrent once all downloads are complete
        winactivate, Torrent 2.0
        send !o
        send a{Down}{Enter}
        winwaitclose, Torrent 2.0
    "
}

w_download_manual_to()
{
    _W_packagename="$1"
    _W_url="$2"
    _W_file="$3"
    _W_shasum="$4"

    # shellcheck disable=SC2154
    case "$media" in
        "download") w_info "FAIL: bug: media type is download, but w_download_manual was called.  Programmer, please change verb's media type to manual_download." ;;
    esac

    if ! test -f "$W_CACHE/$_W_packagename/$_W_file"; then
        case $LANG in
            da*) _W_dlmsg="Hent venligst filen $_W_file fra $_W_url og placér den i $W_CACHE/$_W_packagename, kør derefter dette skript.";;
            de*) _W_dlmsg="Bitte laden Sie $_W_file von $_W_url runter, stellen Sie's in $W_CACHE/$_W_packagename, dann wiederholen Sie dieses Kommando.";;
            pl*) _W_dlmsg="Proszę pobrać plik $_W_file z $_W_url, następnie umieścić go w $W_CACHE/$_W_packagename, a na końcu uruchomić ponownie ten skrypt.";;
            ru*) _W_dlmsg="Пожалуйста, скачайте файл $_W_file по адресу $_W_url, и поместите его в $W_CACHE/$_W_packagename, а затем запустите winetricks заново.";;
            uk*) _W_dlmsg="Будь ласка, звантажте $_W_file з $_W_url, розташуйте в $W_CACHE/$_W_packagename, потім запустіть скрипт знову.";;
            zh_CN*) _W_dlmsg="请从 $_W_url 下载 $_W_file，并置放于 $W_CACHE/$_W_packagename, 然后重新运行 winetricks.";;
            zh_TW*|zh_HK*) _W_dlmsg="請從 $_W_url 下載 $_W_file，并置放於 $W_CACHE/$_W_packagename, 然后重新執行 winetricks.";;
            *) _W_dlmsg="Please download $_W_file from $_W_url, place it in $W_CACHE/$_W_packagename, then re-run this script.";;
        esac

        mkdir -p "$W_CACHE/$_W_packagename"
        w_open_folder "$W_CACHE/$_W_packagename"
        w_open_webpage "$_W_url"
        sleep 3   # give some time for web browser to open
        w_die "$_W_dlmsg"
        # FIXME: wait in loop until file is finished?
    fi

    if test "$_W_shasum"; then
        w_verify_shasum "$_W_shasum" "$W_CACHE/$_W_packagename/$_W_file"
    fi

    unset _W_dlmsg _W_file _W_sha256sum _W_url
}

w_download_manual()
{
    w_download_manual_to "$W_PACKAGE" "$@"
}

# Turn off news, overlays, and friend interaction in Steam
# Run from inside C:\Program Files\Steam
w_steam_safemode()
{
    cat > "$W_TMP/steamconfig.pl" <<"_EOF_"
#!/usr/bin/env perl
# Parse Steam's localconfig.vcf, add settings to it, and write it out again
# The file is a recursive dictionary
#
# FILE :== CONTAINER
#
# VALUE :== "name" "value" NEWLINE
#
# CONTAINER :== "name" NEWLINE "{" NEWLINE ( VALUE | CONTAINER ) * "}" NEWLINE
#
# We load it into a recursive hash.

use strict;
use warnings;

sub read_into_container{
    my( $pcontainer ) = @_;

    $_ = <FILE> || w_die "Can't read first line of container";
    /{/ || w_die "First line of container was not {";
    while (<FILE>) {
        chomp;
        if (/"([^"]*)"\s*"([^"]*)"$/) {
            ${$pcontainer}{$1} = $2;
        } elsif (/"([^"]*)"$/) {
            my( %newcon, $name );
            $name = $1;
            read_into_container(\%newcon);
            ${$pcontainer}{$name} = \%newcon;
        } elsif (/}/) {
            return;
        } else {
            w_die "huh?";
        }
    }
}

sub dump_container{
    my( $pcontainer, $indent ) = @_;
    foreach (sort(keys(%{$pcontainer}))) {
        my( $val ) = ${$pcontainer}{$_};
        if (ref $val eq 'HASH') {
            print "${indent}\"$_\"\n";
            print "${indent}{\n";
            dump_container($val, "$indent\t");
            print "${indent}}\n";
        } else {
            print "${indent}\"${_}\"\t\t\"$val\"\n";
        }
    }
}

# Disable anything unsafe or annoying
sub disable_notifications{
    my( $pcontainer ) = @_;
    ${$pcontainer}{"friends"}{"PersonaStateDesired"} = "1";
    ${$pcontainer}{"friends"}{"Notifications_ShowIngame"} = "0";
    ${$pcontainer}{"friends"}{"Sounds_PlayIngame"} = "0";
    ${$pcontainer}{"friends"}{"Notifications_ShowOnline"} = "0";
    ${$pcontainer}{"friends"}{"Sounds_PlayOnline"} = "0";
    ${$pcontainer}{"friends"}{"Notifications_ShowMessage"} = "0";
    ${$pcontainer}{"friends"}{"Sounds_PlayMessage"} = "0";
    ${$pcontainer}{"friends"}{"AutoSignIntoFriends"} = "0";
    ${$pcontainer}{"News"}{"NotifyAvailableGames"} = "0";
    ${$pcontainer}{"system"}{"EnableGameOverlay"} = "0";
}

# Read the file
my(%top);
open FILE, $ARGV[0] || w_die "cannot open ".$ARGV[0];
my($line);
$line = <FILE> || w_die "Could not read first line from ".$ARGV[0];
$line =~ /"UserLocalConfigStore"/ || w_die "this is not a localconfig.vdf file";
read_into_container(\%top);

# Modify it
disable_notifications(\%top);

# Write modified file
print "\"UserLocalConfigStore\"\n";
print "{\n";
dump_container(\%top, "\t");
print "}\n";
_EOF_

for file in userdata/*/config/localconfig.vdf ; do
    cp "$file" "$file.old"
    perl "$W_TMP"/steamconfig.pl "$file.old" > "$file"
done
}

w_question()
{
    case $WINETRICKS_GUI in
        *zenity) $WINETRICKS_GUI --entry --text "$1" ;;
        *kdialog) $WINETRICKS_GUI --inputbox "$1" ;;
        *xmessage) w_die "sorry, can't ask question with xmessage" ;;
        none)
            # Using printf instead of echo because we don't want a newline
            printf "%s" "$1" >&2 ;
            read -r W_ANSWER ;
            echo "$W_ANSWER";
            unset W_ANSWER;;
    esac
}

# Reads steam username and password from environment, cache, or user
# If had to ask user, cache answer.
w_steam_getid()
{
    #TODO: Translate
    _W_steamidmsg="Please enter your Steam login ID (not email)"
    _W_steampasswordmsg="Please enter your Steam password"

    if test ! "$W_STEAM_ID"; then
        if test -f "$W_CACHE"/steam_userid.txt; then
            W_STEAM_ID=$(cat "$W_CACHE"/steam_userid.txt)
        else
            W_STEAM_ID=$(w_question "$_W_steamidmsg")
            echo "$W_STEAM_ID" > "$W_CACHE"/steam_userid.txt
            chmod 600 "$W_CACHE"/steam_userid.txt
        fi
    fi
    if test ! "$W_STEAM_PASSWORD"; then
        if test -f "$W_CACHE"/steam_password.txt; then
            W_STEAM_PASSWORD=$(cat "$W_CACHE"/steam_password.txt)
        else
            W_STEAM_PASSWORD=$(w_question "$_W_steampasswordmsg")
            echo "$W_STEAM_PASSWORD" > "$W_CACHE"/steam_password.txt
            chmod 600 "$W_CACHE"/steam_password.txt
        fi
    fi
}

# Usage:
# w_steam_install_game steamidnum windowtitle
w_steam_install_game()
{
    _W_steamid=$1
    _W_steamtitle="$2"

    w_steam_getid

    # Install the steam runtime
    WINETRICKS_OPT_SHAREDPREFIX=1 w_call steam

    # Steam puts up a bunch of windows.  Here's the sequence:
    # "Steam - Updating" - wait for it to close.  May appear twice in a row.
    # "Steam - Login" - wait for it to close (credentials already given on cmdline)
    # "Steam" (small window) - connecting, wait for it to close
    # "Steam" (large window) - the main window
    # "Steam - Updates News" - close it forcefully
    # "Install - $title" - send enter, click a couple checkboxes, send enter again
    # "Updating $title" - small download progress dialog
    # "Steam - Ready" game install done.  (Only comes up if main window not up.)

    w_try_cd "$W_PROGRAMS_X86_UNIX/Steam"
    w_ahk_do "
        SetTitleMatchMode 2
        SetWinDelay 500
        ; Run steam once until it finishes its initial update.
        ; For me, this exits at 26%.
        run steam.exe -applaunch $_W_steamid -login $W_STEAM_ID $W_STEAM_PASSWORD
        Loop
        {
            ifWinExist, Steam - Updating
            {
                winwaitclose, Steam
                process close, Steam.exe
                sleep 1000
                ; Run a second time; let it finish updating, then kill it.
                run steam.exe
                winwait Steam - Updating
                winwaitclose
                process close, Steam.exe
                ; Run a third time, have it log in, wait until it has finished connecting
                run steam.exe -applaunch $_W_steamid -login $W_STEAM_ID $W_STEAM_PASSWORD
            }
            ifWinExist, Steam Login
            {
                break
            }
            sleep 500
        }
        ; wait for login window to close
        winwaitclose

        winwait Steam  ; wait for small <<connecting>> window
        winwaitclose
    "

if [ "$STEAM_DVD" = "TRUE" ]; then
    w_ahk_do "
        ; Run a fourth time, have it install the app.
        run steam.exe -install ${W_ISO_MOUNT_LETTER}:\\
    "
else
    w_ahk_do "
        ; Run a fourth time, have it install the app.
        run steam.exe -applaunch $_W_steamid
    "
fi

    w_ahk_do "
        winwait Install - $_W_steamtitle
        if ( w_opt_unattended > 0 ) {
            send {enter}          ; next (for 1st of 3 pages of install dialog)
            sleep 1000
            click 32, 91          ; uncheck create menu item?
            click 32, 119         ; check create desktop icon?
            send {enter}          ; next (for 2nd of 3 pages of install dialog)
            ; dismiss any news dialogs, and click 'next' on third page of install dialog
            loop
            {
                sleep 1000
                ifwinexist Steam - Updates News
                {
                    winclose
                    continue
                }
                ifwinexist Install - $_W_steamtitle
                {
                    winactivate
                    send {enter}      ; next (for 3rd of 3 pages of install dialog)
                }
                ifwinnotexist Install - $_W_steamtitle
                {
                    sleep 1000
                    ifwinnotexist Install - $_W_steamtitle
                        break
                }
            }
        }
    "

if [ "$STEAM_DVD" = "TRUE" ]; then
    # Wait for install to finish
    while true; do
        grep "SetHasAllLocalContent(true) called for $_W_steamid" "$W_PROGRAMS_X86_UNIX/Steam/logs/download_log.txt" && break
        sleep 5
    done
fi

    w_ahk_do "
        ; For DVD's: theoretically, it should be installed now, but most games want to download updates. Do that now.
        ; For regular downloads: relaunch to coax steam into showing its nice small download progress dialog
        process close, Steam.exe
        run steam.exe -login $W_STEAM_ID $W_STEAM_PASSWORD -applaunch $_W_steamid
        winwait Ready -
        process close, Steam.exe
    "

    # Not all users need this disabled, but let's play it safe for now
    if w_workaround_wine_bug 22053 "Disabling in-game notifications to prevent game crashes on some machines."; then
        w_steam_safemode
    fi

    unset _W_steamid _W_steamtitle
}

#----------------------------------------------------------------


# Usage: w_mount "volume name" [filename-to-check [discnum]]
# Some games have two volumes with identical volume names.
# For these, please specify discnum 1 for first disc, discnum 2 for 2nd, etc.,
# else caching can't work.
# FIXME: should take mount option 'unhide' for poorly mastered discs
w_mount()
{
    if test "$3"; then
        WINETRICKS_IMG="$W_CACHE/$W_PACKAGE/$1-$3.iso"
    else
        WINETRICKS_IMG="$W_CACHE/$W_PACKAGE/$1.iso"
    fi
    mkdir -p "$W_CACHE/$W_PACKAGE"

    if test -f "$WINETRICKS_IMG"; then
        winetricks_mount_cached_iso
    else
        if test "$WINETRICKS_OPT_KEEPISOS" = 0 || test "$2"; then
            while true; do
                winetricks_mount_real_volume "$1"
                if test "$2" = "" || test -f "$W_ISO_MOUNT_ROOT/$2"; then
                    break
                else
                    w_warn "Wrong disc inserted, $2 not found."
                fi
            done
        fi

        case "$WINETRICKS_OPT_KEEPISOS" in
            1)
                winetricks_cache_iso "$1"
                winetricks_mount_cached_iso
                ;;
        esac
    fi
}

w_umount()
{
    if test "$WINE" = ""; then
        # Windows
        winetricks_load_vcdmount
        w_try_cd "$VCD_DIR"
        w_try vcdmount.exe /u
    else
        if test "$W_USE_USERMOUNT"; then
            # FUSE-based tools or hdiutil
            if test -d "$W_ISO_USER_MOUNT_ROOT"; then
                "$WINE" eject "${W_ISO_MOUNT_LETTER}:"
                cat > "$W_TMP"/unset_type_cdrom.reg <<_EOF_
REGEDIT4

[HKEY_LOCAL_MACHINE\\Software\\Wine\\Drives]
"${W_ISO_MOUNT_LETTER}:"=-
_EOF_
                w_try_regedit "$W_TMP"/unset_type_cdrom.reg
                rm -f "$WINEPREFIX/dosdevices/${W_ISO_MOUNT_LETTER}:"
                rm -f "$WINEPREFIX/dosdevices/${W_ISO_MOUNT_LETTER}::"

                case "$WINETRICKS_ISO_MOUNT" in
                    hdiutil)
                        "$WINETRICKS_ISO_MOUNT" detach "$W_ISO_USER_MOUNT_ROOT"
                        ;;
                    *)
                        # -uz lazy unmount in case executable still running
                        fusermount -uz "$W_ISO_USER_MOUNT_ROOT"
                        ;;
                esac
                w_try rmdir "$W_ISO_USER_MOUNT_ROOT"
            fi
            W_ISO_MOUNT_ROOT=/mnt/winetricks
        else
            # sudo + umount
            echo "Running $WINETRICKS_SUDO umount $W_ISO_MOUNT_ROOT"

            case "$WINETRICKS_SUDO" in
                gksu*|kdesudo)
                    # -l lazy unmount in case executable still running
                    "$WINETRICKS_SUDO" "umount -l $W_ISO_MOUNT_ROOT"
                    w_try "$WINETRICKS_SUDO" "rm -rf $W_ISO_MOUNT_ROOT"
                    ;;
                kdesu)
                    "$WINETRICKS_SUDO" -c "umount -l $W_ISO_MOUNT_ROOT"
                    w_try "$WINETRICKS_SUDO" -c "rm -rf $W_ISO_MOUNT_ROOT"
                    ;;
                *)
                    "$WINETRICKS_SUDO" umount -l "$W_ISO_MOUNT_ROOT"
                    w_try "$WINETRICKS_SUDO" rm -rf "$W_ISO_MOUNT_ROOT"
                    ;;
            esac

            "$WINE" eject "${W_ISO_MOUNT_LETTER}:"
            rm -f "$WINEPREFIX/dosdevices/${W_ISO_MOUNT_LETTER}:"
            rm -f "$WINEPREFIX/dosdevices/${W_ISO_MOUNT_LETTER}::"
        fi
    fi
}

w_ahk_do()
{
    if ! test -f "$W_CACHE/ahk/AutoHotkey.exe"; then
        w_download_to ahk ${W_DOWNLOADURLS}/AutoHotkey104805_Install.exe 4311c3e7c29ed2d67f415138360210bc2f55ff78758b20b003b91d775ee207b9
        w_try_7z "$W_CACHE/ahk" "$W_CACHE/ahk/AutoHotkey104805_Install.exe" AutoHotkey.exe AU3_Spy.exe
        chmod +x "$W_CACHE/ahk/AutoHotkey.exe"
    fi

    # Previously this used printf + sed, but that was broken with BSD sed (FreeBSD/OS X):
    # https://github.com/Winetricks/winetricks/issues/697
    # So now using trying awk instead (next, perl):
    cat <<_EOF_ | awk 'sub("$", "\r")' > "${W_TMP}/${W_PACKAGE}.ahk"
w_opt_unattended = ${W_OPT_UNATTENDED:-0}
$@
_EOF_
    w_try "${WINE}" "${W_CACHE_WIN}\\ahk\\AutoHotkey.exe" "${W_TMP_WIN}\\${W_PACKAGE}.ahk"
}

# Function to protect Wine-specific sections of code.
# Outputs a message to console explaining what's being skipped.
# Usage:
#   if w_skip_windows name-of-operation; then
#      return
#   fi
#   ... do something that doesn't make sense on Windows ...

w_skip_windows()
{
    case "$W_PLATFORM" in
        windows_cmd)
            echo "Skipping operation '$1' on Windows"
            return 0
            ;;
    esac
    return 1
}

# for common code in w_override_dlls and w_override_app_dlls
w_common_override_dll()
{
    _W_mode="$1"
    module="$2"

    # Remove wine's builtin manifest, if present. Use:
    # wineboot ; find "$WINEPREFIX"/drive_c/windows/winsxs/ -iname \*deadbeef.manifest | sort
    case "$W_PACKAGE" in
        comctl32)
            w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef.manifest
            w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef.manifest
            ;;
        vcrun2005)
            w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/amd64_microsoft.vc80.atl_1fc8b3b9a1e18e3b_8.0.50727.4053_none_deadbeef.manifest
            w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/amd64_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.4053_none_deadbeef.manifest
            w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/x86_microsoft.vc80.atl_1fc8b3b9a1e18e3b_8.0.50727.4053_none_deadbeef.manifest
            w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.4053_none_deadbeef.manifest

            # These are 32-bit only?
            w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/x86_microsoft.vc80.mfc_1fc8b3b9a1e18e3b_8.0.50727.6195_none_deadbeef.manifest
            w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/x86_microsoft.vc80.mfcloc_1fc8b3b9a1e18e3b_8.0.50727.6195_none_deadbeef.manifest
            w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/x86_microsoft.vc80.openmp_1fc8b3b9a1e18e3b_8.0.50727.6195_none_deadbeef.manifest
            ;;
        vcrun2008)
            w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/amd64_microsoft.vc90.atl_1fc8b3b9a1e18e3b_9.0.30729.6161_none_deadbeef.manifest
            w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/amd64_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_deadbeef.manifest
            w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/x86_microsoft.vc90.atl_1fc8b3b9a1e18e3b_9.0.30729.6161_none_deadbeef.manifest
            w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_deadbeef.manifest

            # These are 32-bit only?
            w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/x86_microsoft.vc90.mfc_1fc8b3b9a1e18e3b_9.0.30729.6161_none_deadbeef.manifest
            w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/x86_microsoft.vc90.mfcloc_1fc8b3b9a1e18e3b_9.0.30729.6161_none_deadbeef.manifest
            w_try rm -rf "$W_WINDIR_UNIX"/winsxs/manifests/x86_microsoft.vc90.openmp_1fc8b3b9a1e18e3b_9.0.30729.6161_none_deadbeef.manifest
            ;;
    esac

    if [ "$_W_mode" = default ] ; then
        # To delete a registry key, give an unquoted dash as value
        echo "\"*$module\"=-" >> "$W_TMP"/override-dll.reg
    else
        # Note: if you want to override even DLLs loaded with an absolute
        # path, you need to add an asterisk:
        echo "\"*$module\"=\"$_W_mode\"" >> "$W_TMP"/override-dll.reg
    fi
}

w_override_dlls()
{
    w_skip_windows w_override_dlls && return

    _W_mode=$1
    case $_W_mode in
        *=*)
            w_die "w_override_dlls: unknown mode $_W_mode.
Usage: 'w_override_dlls mode[,mode] dll ...'." ;;
        disabled)
            _W_mode="" ;;
    esac

    shift

    echo "Using $_W_mode override for following DLLs: $*"
    cat > "$W_TMP"/override-dll.reg <<_EOF_
REGEDIT4

[HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides]
_EOF_
    while test "$1" != ""; do
        w_common_override_dll "$_W_mode" "$1"
        shift
    done

    w_try_regedit "$W_TMP_WIN"\\override-dll.reg

    unset _W_mode
}

w_override_no_dlls()
{
    w_skip_windows override && return

    w_try_regedit /d "HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides"
}

w_override_all_dlls()
{
    # Disable all known native Microsoft DLLs in favor of Wine's built-in ones
    # Generated with:
    # find ./dlls -maxdepth 1 -type d ! -iname "*.dll16" ! -iname "*.drv*" ! -iname "*.ds" ! -iname "*.exe*" ! -iname "*.tlb" ! -iname "*.vxd" -print | sed \
    #   -e '/^.*\/adsiid$/ d' \
    #   -e '/^.*\/advapi32$/ d' \
    #   -e '/^.*\/capi2032$/ d' \
    #   -e '/^.*\/dbghelp$/ d' \
    #   -e '/^.*\/ddraw$/ d' \
    #   -e '/^.*\/dlls$/ d' \
    #   -e '/^.*\/dmoguids$/ d' \
    #   -e '/^.*\/dxerr8$/ d' \
    #   -e '/^.*\/dxerr9$/ d' \
    #   -e '/^.*\/dxguid$/ d' \
    #   -e '/^.*\/gdi32$/ d' \
    #   -e '/^.*\/glu32$/ d' \
    #   -e '/^.*\/icmp$/ d' \
    #   -e '/^.*\/iphlpapi$/ d' \
    #   -e '/^.*\/kernel32$/ d' \
    #   -e '/^.*\/l3codeca.acm$/ d' \
    #   -e '/^.*\/mfuuid$/ d' \
    #   -e '/^.*\/mountmgr.sys$/ d' \
    #   -e '/^.*\/mswsock$/ d' \
    #   -e '/^.*\/ntdll$/ d' \
    #   -e '/^.*\/opengl32$/ d' \
    #   -e '/^.*\/secur32$/ d' \
    #   -e '/^.*\/strmbase$/ d' \
    #   -e '/^.*\/strmiids$/ d' \
    #   -e '/^.*\/twain_32$/ d' \
    #   -e '/^.*\/unicows$/ d' \
    #   -e '/^.*\/user32$/ d' \
    #   -e '/^.*\/uuid$/ d' \
    #   -e '/^.*\/vdmdbg$/ d' \
    #   -e '/^.*\/w32skrnl$/ d' \
    #   -e '/^.*\/winecrt0$/ d' \
    #   -e '/^.*\/wined3d$/ d' \
    #   -e '/^.*\/winemp3.acm$/ d' \
    #   -e '/^.*\/wineqtdecoder$/ d' \
    #   -e '/^.*\/winmm$/ d' \
    #   -e '/^.*\/wintab32$/ d' \
    #   -e '/^.*\/wmcodecdspuuid$/ d' \
    #   -e '/^.*\/wnaspi32$/ d' \
    #   -e '/^.*\/wow32$/ d' \
    #   -e '/^.*\/ws2_32$/ d' \
    #   -e '/^.*\/wsock32$/ d' \
    #   -e 's,.*/,        ,' | sort | fmt -63 | sed 's/$/ \\/'
    #
    # 2018-12-10: Last list update (wine-4.0-rc1)
    w_override_dlls builtin \
        acledit aclui activeds actxprxy adsldp adsldpc advpack \
        amstream api-ms-win-appmodel-identity-l1-1-0 \
        api-ms-win-appmodel-runtime-l1-1-1 \
        api-ms-win-appmodel-runtime-l1-1-2 \
        api-ms-win-core-apiquery-l1-1-0 \
        api-ms-win-core-appcompat-l1-1-1 \
        api-ms-win-core-appinit-l1-1-0 \
        api-ms-win-core-atoms-l1-1-0 \
        api-ms-win-core-bem-l1-1-0 api-ms-win-core-com-l1-1-0 \
        api-ms-win-core-com-l1-1-1 api-ms-win-core-comm-l1-1-0 \
        api-ms-win-core-com-private-l1-1-0 \
        api-ms-win-core-console-l1-1-0 \
        api-ms-win-core-console-l2-1-0 \
        api-ms-win-core-crt-l1-1-0 api-ms-win-core-crt-l2-1-0 \
        api-ms-win-core-datetime-l1-1-0 \
        api-ms-win-core-datetime-l1-1-1 \
        api-ms-win-core-debug-l1-1-0 \
        api-ms-win-core-debug-l1-1-1 \
        api-ms-win-core-delayload-l1-1-0 \
        api-ms-win-core-delayload-l1-1-1 \
        api-ms-win-core-errorhandling-l1-1-0 \
        api-ms-win-core-errorhandling-l1-1-1 \
        api-ms-win-core-errorhandling-l1-1-2 \
        api-ms-win-core-errorhandling-l1-1-3 \
        api-ms-win-core-fibers-l1-1-0 \
        api-ms-win-core-fibers-l1-1-1 \
        api-ms-win-core-file-l1-1-0 \
        api-ms-win-core-file-l1-2-0 \
        api-ms-win-core-file-l1-2-1 \
        api-ms-win-core-file-l1-2-2 \
        api-ms-win-core-file-l2-1-0 \
        api-ms-win-core-file-l2-1-1 \
        api-ms-win-core-file-l2-1-2 \
        api-ms-win-core-handle-l1-1-0 \
        api-ms-win-core-heap-l1-1-0 \
        api-ms-win-core-heap-l1-2-0 \
        api-ms-win-core-heap-l2-1-0 \
        api-ms-win-core-heap-obsolete-l1-1-0 \
        api-ms-win-core-interlocked-l1-1-0 \
        api-ms-win-core-interlocked-l1-2-0 \
        api-ms-win-core-io-l1-1-0 api-ms-win-core-io-l1-1-1 \
        api-ms-win-core-job-l1-1-0 api-ms-win-core-job-l2-1-0 \
        api-ms-win-core-kernel32-legacy-l1-1-0 \
        api-ms-win-core-kernel32-legacy-l1-1-1 \
        api-ms-win-core-kernel32-private-l1-1-1 \
        api-ms-win-core-largeinteger-l1-1-0 \
        api-ms-win-core-libraryloader-l1-1-0 \
        api-ms-win-core-libraryloader-l1-1-1 \
        api-ms-win-core-libraryloader-l1-2-0 \
        api-ms-win-core-libraryloader-l1-2-1 \
        api-ms-win-core-libraryloader-l1-2-2 \
        api-ms-win-core-localization-l1-1-0 \
        api-ms-win-core-localization-l1-2-0 \
        api-ms-win-core-localization-l1-2-1 \
        api-ms-win-core-localization-l2-1-0 \
        api-ms-win-core-localization-obsolete-l1-1-0 \
        api-ms-win-core-localization-obsolete-l1-2-0 \
        api-ms-win-core-localization-obsolete-l1-3-0 \
        api-ms-win-core-localization-private-l1-1-0 \
        api-ms-win-core-localregistry-l1-1-0 \
        api-ms-win-core-memory-l1-1-0 \
        api-ms-win-core-memory-l1-1-1 \
        api-ms-win-core-memory-l1-1-2 \
        api-ms-win-core-misc-l1-1-0 \
        api-ms-win-core-namedpipe-l1-1-0 \
        api-ms-win-core-namedpipe-l1-2-0 \
        api-ms-win-core-namespace-l1-1-0 \
        api-ms-win-core-normalization-l1-1-0 \
        api-ms-win-core-path-l1-1-0 \
        api-ms-win-core-privateprofile-l1-1-1 \
        api-ms-win-core-processenvironment-l1-1-0 \
        api-ms-win-core-processenvironment-l1-2-0 \
        api-ms-win-core-processthreads-l1-1-0 \
        api-ms-win-core-processthreads-l1-1-1 \
        api-ms-win-core-processthreads-l1-1-2 \
        api-ms-win-core-processthreads-l1-1-3 \
        api-ms-win-core-processtopology-obsolete-l1-1-0 \
        api-ms-win-core-profile-l1-1-0 \
        api-ms-win-core-psapi-ansi-l1-1-0 \
        api-ms-win-core-psapi-l1-1-0 \
        api-ms-win-core-psapi-obsolete-l1-1-0 \
        api-ms-win-core-quirks-l1-1-0 \
        api-ms-win-core-realtime-l1-1-0 \
        api-ms-win-core-registry-l1-1-0 \
        api-ms-win-core-registry-l2-1-0 \
        api-ms-win-core-registryuserspecific-l1-1-0 \
        api-ms-win-core-rtlsupport-l1-1-0 \
        api-ms-win-core-rtlsupport-l1-2-0 \
        api-ms-win-core-shlwapi-legacy-l1-1-0 \
        api-ms-win-core-shlwapi-obsolete-l1-1-0 \
        api-ms-win-core-shlwapi-obsolete-l1-2-0 \
        api-ms-win-core-shutdown-l1-1-0 \
        api-ms-win-core-sidebyside-l1-1-0 \
        api-ms-win-core-stringansi-l1-1-0 \
        api-ms-win-core-string-l1-1-0 \
        api-ms-win-core-string-l2-1-0 \
        api-ms-win-core-stringloader-l1-1-1 \
        api-ms-win-core-string-obsolete-l1-1-0 \
        api-ms-win-core-synch-ansi-l1-1-0 \
        api-ms-win-core-synch-l1-1-0 \
        api-ms-win-core-synch-l1-2-0 \
        api-ms-win-core-synch-l1-2-1 \
        api-ms-win-core-sysinfo-l1-1-0 \
        api-ms-win-core-sysinfo-l1-2-0 \
        api-ms-win-core-sysinfo-l1-2-1 \
        api-ms-win-core-threadpool-l1-1-0 \
        api-ms-win-core-threadpool-l1-2-0 \
        api-ms-win-core-threadpool-legacy-l1-1-0 \
        api-ms-win-core-threadpool-private-l1-1-0 \
        api-ms-win-core-timezone-l1-1-0 \
        api-ms-win-core-toolhelp-l1-1-0 \
        api-ms-win-core-url-l1-1-0 api-ms-win-core-util-l1-1-0 \
        api-ms-win-core-versionansi-l1-1-0 \
        api-ms-win-core-version-l1-1-0 \
        api-ms-win-core-version-l1-1-1 \
        api-ms-win-core-version-private-l1-1-0 \
        api-ms-win-core-windowserrorreporting-l1-1-0 \
        api-ms-win-core-winrt-error-l1-1-0 \
        api-ms-win-core-winrt-error-l1-1-1 \
        api-ms-win-core-winrt-errorprivate-l1-1-1 \
        api-ms-win-core-winrt-l1-1-0 \
        api-ms-win-core-winrt-registration-l1-1-0 \
        api-ms-win-core-winrt-roparameterizediid-l1-1-0 \
        api-ms-win-core-winrt-string-l1-1-0 \
        api-ms-win-core-winrt-string-l1-1-1 \
        api-ms-win-core-wow64-l1-1-0 \
        api-ms-win-core-wow64-l1-1-1 \
        api-ms-win-core-xstate-l1-1-0 \
        api-ms-win-core-xstate-l2-1-0 \
        api-ms-win-crt-conio-l1-1-0 \
        api-ms-win-crt-convert-l1-1-0 \
        api-ms-win-crt-environment-l1-1-0 \
        api-ms-win-crt-filesystem-l1-1-0 \
        api-ms-win-crt-heap-l1-1-0 \
        api-ms-win-crt-locale-l1-1-0 \
        api-ms-win-crt-math-l1-1-0 \
        api-ms-win-crt-multibyte-l1-1-0 \
        api-ms-win-crt-private-l1-1-0 \
        api-ms-win-crt-process-l1-1-0 \
        api-ms-win-crt-runtime-l1-1-0 \
        api-ms-win-crt-stdio-l1-1-0 \
        api-ms-win-crt-string-l1-1-0 \
        api-ms-win-crt-time-l1-1-0 \
        api-ms-win-crt-utility-l1-1-0 \
        api-ms-win-devices-config-l1-1-0 \
        api-ms-win-devices-config-l1-1-1 \
        api-ms-win-devices-query-l1-1-1 \
        api-ms-win-downlevel-advapi32-l1-1-0 \
        api-ms-win-downlevel-advapi32-l2-1-0 \
        api-ms-win-downlevel-normaliz-l1-1-0 \
        api-ms-win-downlevel-ole32-l1-1-0 \
        api-ms-win-downlevel-shell32-l1-1-0 \
        api-ms-win-downlevel-shlwapi-l1-1-0 \
        api-ms-win-downlevel-shlwapi-l2-1-0 \
        api-ms-win-downlevel-user32-l1-1-0 \
        api-ms-win-downlevel-version-l1-1-0 \
        api-ms-win-dx-d3dkmt-l1-1-0 \
        api-ms-win-eventing-classicprovider-l1-1-0 \
        api-ms-win-eventing-consumer-l1-1-0 \
        api-ms-win-eventing-controller-l1-1-0 \
        api-ms-win-eventing-legacy-l1-1-0 \
        api-ms-win-eventing-provider-l1-1-0 \
        api-ms-win-eventlog-legacy-l1-1-0 \
        api-ms-win-gdi-dpiinfo-l1-1-0 \
        api-ms-win-mm-joystick-l1-1-0 \
        api-ms-win-mm-misc-l1-1-1 api-ms-win-mm-mme-l1-1-0 \
        api-ms-win-mm-time-l1-1-0 \
        api-ms-win-ntuser-dc-access-l1-1-0 \
        api-ms-win-ntuser-rectangle-l1-1-0 \
        api-ms-win-ntuser-sysparams-l1-1-0 \
        api-ms-win-perf-legacy-l1-1-0 \
        api-ms-win-power-base-l1-1-0 \
        api-ms-win-power-setting-l1-1-0 \
        api-ms-win-rtcore-ntuser-draw-l1-1-0 \
        api-ms-win-rtcore-ntuser-private-l1-1-0 \
        api-ms-win-rtcore-ntuser-private-l1-1-4 \
        api-ms-win-rtcore-ntuser-window-l1-1-0 \
        api-ms-win-rtcore-ntuser-winevent-l1-1-0 \
        api-ms-win-rtcore-ntuser-wmpointer-l1-1-0 \
        api-ms-win-rtcore-ntuser-wmpointer-l1-1-3 \
        api-ms-win-security-activedirectoryclient-l1-1-0 \
        api-ms-win-security-audit-l1-1-1 \
        api-ms-win-security-base-l1-1-0 \
        api-ms-win-security-base-l1-2-0 \
        api-ms-win-security-base-private-l1-1-1 \
        api-ms-win-security-credentials-l1-1-0 \
        api-ms-win-security-cryptoapi-l1-1-0 \
        api-ms-win-security-grouppolicy-l1-1-0 \
        api-ms-win-security-lsalookup-l1-1-0 \
        api-ms-win-security-lsalookup-l1-1-1 \
        api-ms-win-security-lsalookup-l2-1-0 \
        api-ms-win-security-lsalookup-l2-1-1 \
        api-ms-win-security-lsapolicy-l1-1-0 \
        api-ms-win-security-provider-l1-1-0 \
        api-ms-win-security-sddl-l1-1-0 \
        api-ms-win-security-systemfunctions-l1-1-0 \
        api-ms-win-service-core-l1-1-0 \
        api-ms-win-service-core-l1-1-1 \
        api-ms-win-service-management-l1-1-0 \
        api-ms-win-service-management-l2-1-0 \
        api-ms-win-service-private-l1-1-1 \
        api-ms-win-service-winsvc-l1-1-0 \
        api-ms-win-service-winsvc-l1-2-0 \
        api-ms-win-shcore-obsolete-l1-1-0 \
        api-ms-win-shcore-scaling-l1-1-1 \
        api-ms-win-shcore-stream-l1-1-0 \
        api-ms-win-shcore-thread-l1-1-0 \
        api-ms-win-shell-shellcom-l1-1-0 \
        api-ms-win-shell-shellfolders-l1-1-0 apphelp \
        appwiz.cpl atl atl100 atl110 atl80 atl90 atmlib \
        authz avicap32 avifil32 avrt bcrypt bluetoothapis \
        browseui bthprops.cpl cabinet cards cdosys cfgmgr32 \
        clusapi combase comcat comctl32 comdlg32 compstui \
        comsvcs concrt140 connect credui crtdll crypt32 \
        cryptdlg cryptdll cryptext cryptnet cryptui ctapi32 \
        ctl3d32 d2d1 d3d10 d3d10_1 d3d10core d3d11 d3d12 d3d8 \
        d3d9 d3dcompiler_33 d3dcompiler_34 d3dcompiler_35 \
        d3dcompiler_36 d3dcompiler_37 d3dcompiler_38 \
        d3dcompiler_39 d3dcompiler_40 d3dcompiler_41 \
        d3dcompiler_42 d3dcompiler_43 d3dcompiler_46 \
        d3dcompiler_47 d3dim d3drm d3dx10_33 d3dx10_34 \
        d3dx10_35 d3dx10_36 d3dx10_37 d3dx10_38 d3dx10_39 \
        d3dx10_40 d3dx10_41 d3dx10_42 d3dx10_43 d3dx11_42 \
        d3dx11_43 d3dx9_24 d3dx9_25 d3dx9_26 d3dx9_27 \
        d3dx9_28 d3dx9_29 d3dx9_30 d3dx9_31 d3dx9_32 d3dx9_33 \
        d3dx9_34 d3dx9_35 d3dx9_36 d3dx9_37 d3dx9_38 d3dx9_39 \
        d3dx9_40 d3dx9_41 d3dx9_42 d3dx9_43 d3dxof davclnt \
        dbgeng dciman32 ddrawex devenum dhcpcsvc dhtmled.ocx \
        difxapi dinput dinput8 dispex dmband dmcompos dmime \
        dmloader dmscript dmstyle dmsynth dmusic dmusic32 \
        dnsapi dplay dplayx dpnaddr dpnet dpnhpast dpnlobby \
        dpvoice dpwsockx drmclien dsound dsquery dssenh \
        dswave dwmapi dwrite dx8vb dxdiagn dxgi dxva2 esent \
        evr explorerframe ext-ms-win-authz-context-l1-1-0 \
        ext-ms-win-domainjoin-netjoin-l1-1-0 \
        ext-ms-win-dwmapi-ext-l1-1-0 \
        ext-ms-win-gdi-dc-create-l1-1-1 \
        ext-ms-win-gdi-dc-l1-2-0 ext-ms-win-gdi-devcaps-l1-1-0 \
        ext-ms-win-gdi-draw-l1-1-1 \
        ext-ms-win-gdi-render-l1-1-0 \
        ext-ms-win-kernel32-package-current-l1-1-0 \
        ext-ms-win-kernel32-package-l1-1-1 \
        ext-ms-win-ntuser-draw-l1-1-0 \
        ext-ms-win-ntuser-gui-l1-3-0 \
        ext-ms-win-ntuser-keyboard-l1-3-0 \
        ext-ms-win-ntuser-message-l1-1-1 \
        ext-ms-win-ntuser-misc-l1-2-0 \
        ext-ms-win-ntuser-misc-l1-5-1 \
        ext-ms-win-ntuser-mouse-l1-1-0 \
        ext-ms-win-ntuser-private-l1-1-1 \
        ext-ms-win-ntuser-private-l1-3-1 \
        ext-ms-win-ntuser-rectangle-ext-l1-1-0 \
        ext-ms-win-ntuser-uicontext-ext-l1-1-0 \
        ext-ms-win-ntuser-windowclass-l1-1-1 \
        ext-ms-win-ntuser-window-l1-1-1 \
        ext-ms-win-ntuser-window-l1-1-4 \
        ext-ms-win-oleacc-l1-1-0 \
        ext-ms-win-ras-rasapi32-l1-1-0 \
        ext-ms-win-rtcore-gdi-devcaps-l1-1-0 \
        ext-ms-win-rtcore-gdi-object-l1-1-0 \
        ext-ms-win-rtcore-gdi-rgn-l1-1-0 \
        ext-ms-win-rtcore-ntuser-cursor-l1-1-0 \
        ext-ms-win-rtcore-ntuser-dc-access-l1-1-0 \
        ext-ms-win-rtcore-ntuser-dpi-l1-1-0 \
        ext-ms-win-rtcore-ntuser-dpi-l1-2-0 \
        ext-ms-win-rtcore-ntuser-rawinput-l1-1-0 \
        ext-ms-win-rtcore-ntuser-syscolors-l1-1-0 \
        ext-ms-win-rtcore-ntuser-sysparams-l1-1-0 \
        ext-ms-win-security-credui-l1-1-0 \
        ext-ms-win-security-cryptui-l1-1-0 \
        ext-ms-win-uxtheme-themes-l1-1-0 faultrep feclient \
        fltlib fltmgr.sys fntcache fontsub fusion fwpuclnt \
        gameux gdiplus gpkcsp hal hhctrl.ocx hid hidclass.sys \
        hlink hnetcfg httpapi iccvid ieframe ieproxy \
        imaadp32.acm imagehlp imm32 inetcomm inetcpl.cpl \
        inetmib1 infosoft initpki inkobj inseng iprop \
        irprops.cpl itircl itss joy.cpl jscript jsproxy \
        kerberos kernelbase ksuser ktmw32 loadperf localspl \
        localui lz32 mapi32 mapistub mciavi32 mcicda mciqtz32 \
        mciseq mciwave mf mf3216 mfplat mfreadwrite mgmtapi \
        midimap mlang mmcndmgr mmdevapi mp3dmod mpr mprapi \
        msacm32 msadp32.acm msasn1 mscat32 mscms mscoree \
        msctf msctfp msdaps msdelta msdmo msdrm msftedit \
        msg711.acm msgsm32.acm mshtml msi msident msimg32 \
        msimsg msimtf msisip msisys.ocx msls31 msnet32 \
        mspatcha msports msrle32 msscript.ocx mssign32 \
        mssip32 mstask msvcirt msvcm80 msvcm90 msvcp100 \
        msvcp110 msvcp120 msvcp120_app msvcp140 msvcp60 \
        msvcp70 msvcp71 msvcp80 msvcp90 msvcr100 msvcr110 \
        msvcr120 msvcr120_app msvcr70 msvcr71 msvcr80 \
        msvcr90 msvcrt msvcrt20 msvcrt40 msvcrtd msvfw32 \
        msvidc32 msxml msxml2 msxml3 msxml4 msxml6 mtxdm \
        ncrypt nddeapi ndis.sys netapi32 netcfgx netprofm \
        newdev ninput normaliz npmshtml npptools ntdsapi \
        ntprint objsel odbc32 odbccp32 odbccu32 ole32 oleacc \
        oleaut32 olecli32 oledb32 oledlg olepro32 olesvr32 \
        olethk32 opcservices openal32 opencl packager pdh \
        photometadatahandler pidgen powrprof printui prntvpt \
        propsys psapi pstorec qcap qedit qmgr qmgrprxy \
        quartz query qwave rasapi32 rasdlg regapi resutils \
        riched20 riched32 rpcrt4 rsabase rsaenh rstrtmgr \
        rtutils samlib sapi sas scarddlg sccbase schannel \
        schedsvc scrobj scrrun scsiport.sys security sensapi \
        serialui setupapi sfc sfc_os shcore shdoclc shdocvw \
        shell32 shfolder shlwapi slbcsp slc snmpapi softpub \
        spoolss srclient sspicli sti strmdll svrapi sxs \
        t2embed tapi32 taskschd tdh tdi.sys traffic tzres \
        ucrtbase uiautomationcore uiribbon updspapi url \
        urlmon usbd.sys userenv usp10 uxtheme vbscript \
        vcomp vcomp100 vcomp110 vcomp120 vcomp140 vcomp90 \
        vcruntime140 version virtdisk vssapi vulkan-1 wbemdisp \
        wbemprox wdscore webservices wer wevtapi wiaservc \
        wimgapi windowscodecs windowscodecsext winebus.sys \
        winegstreamer winehid.sys winemapi winevulkan wing32 \
        winhttp wininet winnls32 winscard winsta wintrust \
        winusb wlanapi wldap32 wmasf wmi wmiutils wmp wmphoto \
        wmvcore wpc wpcap wsdapi wshom.ocx wsnmp32 wtsapi32 \
        wuapi wuaueng x3daudio1_0 x3daudio1_1 x3daudio1_2 \
        x3daudio1_3 x3daudio1_4 x3daudio1_5 x3daudio1_6 \
        x3daudio1_7 xapofx1_1 xapofx1_2 xapofx1_3 xapofx1_4 \
        xapofx1_5 xaudio2_0 xaudio2_1 xaudio2_2 xaudio2_3 \
        xaudio2_4 xaudio2_5 xaudio2_6 xaudio2_7 xaudio2_8 \
        xaudio2_9 xinput1_1 xinput1_2 xinput1_3 xinput1_4 \
        xinput9_1_0 xmllite xolehlp xpsprint xpssvcs \

        # blank line so you don't have to remove the extra trailing \
}

w_override_app_dlls()
{
    w_skip_windows w_override_app_dlls && return

    _W_app=$1
    shift
    _W_mode=$1
    shift

    # Fixme: handle comma-separated list of modes
    case $_W_mode in
        b|builtin) _W_mode=builtin ;;
        n|native) _W_mode=native ;;
        default) _W_mode=default ;;
        d|disabled) _W_mode="" ;;
        *)
        w_die "w_override_app_dlls: unknown mode $_W_mode.  (want native, builtin, default, or disabled)
Usage: 'w_override_app_dlls app mode dll ...'." ;;
    esac

    echo "Using $_W_mode override for following DLLs when running $_W_app: $*"
    (
        echo REGEDIT4
        echo ""
        echo "[HKEY_CURRENT_USER\\Software\\Wine\\AppDefaults\\$_W_app\\DllOverrides]"
    ) > "$W_TMP"/override-dll.reg

    while test "$1" != ""; do
        w_common_override_dll "$_W_mode" "$1"
        shift
    done

    w_try_regedit "$W_TMP_WIN"\\override-dll.reg
    w_try rm "$W_TMP"/override-dll.reg
    unset _W_app _W_mode
}

# Has to be set in a few places...
w_set_winver()
{
    w_skip_windows w_set_winver && return
    # FIXME: This should really be done with winecfg, but it has no CLI options.
    # Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45616

    # First, delete any lingering version info, otherwise it may conflict:
    (
    "$WINE" reg delete "HKLM\\Software\\Microsoft\\Windows\\CurrentVersion" /v SubVersionNumber /f || true
    "$WINE" reg delete "HKLM\\Software\\Microsoft\\Windows\\CurrentVersion" /v VersionNumber /f || true
    "$WINE" reg delete "HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion" /v CSDVersion /f || true
    "$WINE" reg delete "HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion" /v CurrentBuildNumber /f || true
    "$WINE" reg delete "HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion" /v CurrentVersion /f || true
    "$WINE" reg delete "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /f || true
    "$WINE" reg delete "HKLM\\System\\CurrentControlSet\\Control\\ServiceCurrent" /v OS /f || true
    "$WINE" reg delete "HKLM\\System\\CurrentControlSet\\Control\\Windows" /v CSDVersion /f || true
    "$WINE" reg delete "HKCU\\Software\\Wine" /v Version /f || true
    "$WINE" reg delete "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /f || true
    ) > /dev/null 2>&1

    case "$1" in
        win31)
            echo "Setting Windows version to $1"
            cat > "$W_TMP"/set-winver.reg <<_EOF_
REGEDIT4

[HKEY_USERS\\S-1-5-4\\Software\\Wine]
"Version"="win31"

_EOF_
            w_try_regedit "$W_TMP_WIN"\\set-winver.reg
            return
            ;;
        win95)
            # This key is only used for Windows 95/98:

            echo "Setting Windows version to $1"
            cat > "$W_TMP"/set-winver.reg <<_EOF_
REGEDIT4

[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion]
"ProductName"="Microsoft Windows 95"
"SubVersionNumber"=""
"VersionNumber"="4.0.950"

_EOF_
            w_try_regedit "$W_TMP_WIN"\\set-winver.reg
            return
            ;;
        win98)
            # This key is only used for Windows 95/98:

            echo "Setting Windows version to $1"
            cat > "$W_TMP"/set-winver.reg <<_EOF_
REGEDIT4

[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion]
"ProductName"="Microsoft Windows 98"
"SubVersionNumber"=" A "
"VersionNumber"="4.10.2222"

_EOF_
            w_try_regedit "$W_TMP_WIN"\\set-winver.reg
            return
            ;;
        nt40)
            # Similar to modern version, but sets two extra keys:

            echo "Setting Windows version to $1"
            cat > "$W_TMP"/set-winver.reg <<_EOF_
REGEDIT4

[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion]
"CSDVersion"="Service Pack 6a"
"CurrentBuildNumber"="1381"
"CurrentVersion"="4.0"

[HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\ProductOptions]
"ProductType"="WinNT"

[HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\ServiceCurrent]
"OS"="Windows_NT"

[HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Windows]
"CSDVersion"=dword:00000600

_EOF_
            w_try_regedit "$W_TMP_WIN"\\set-winver.reg
            return
            ;;
        win2k)
            csdversion="Service Pack 4"
            currentbuildnumber="2195"
            currentversion="5.0"
            csdversion_hex=dword:00000400
            ;;
        winxp)
            # Special case, afaik it's the only Windows version that has different version numbers for 32/64-bit
            # So ensure we set the arch appropriate version:
            if [ "$W_ARCH" = "win32" ]; then
                csdversion="Service Pack 3"
                currentbuildnumber="2600"
                currentversion="5.1"
                csdversion_hex=dword:00000300
            elif [ "$W_ARCH" = "win64" ]; then
                csdversion="Service Pack 2"
                currentbuildnumber="3790"
                currentversion="5.2"
                csdversion_hex=dword:00000200
                "$WINE" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "WinNT" /f
            else
                w_die "Invalid W_ARCH $W_ARCH"
            fi
            ;;
        win2k3)
            csdversion="Service Pack 2"
            currentbuildnumber="3790"
            currentversion="5.2"
            csdversion_hex=dword:00000200
            "$WINE" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "ServerNT" /f
            ;;
        vista)
            csdversion="Service Pack 2"
            currentbuildnumber="6002"
            currentversion="6.0"
            csdversion_hex=dword:00000200
            "$WINE" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "WinNT" /f
            ;;
        win7|default)
            csdversion="Service Pack 1"
            currentbuildnumber="7601"
            currentversion="6.1"
            csdversion_hex=dword:00000100
            "$WINE" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "WinNT" /f
            ;;
        win2k8)
            csdversion="Service Pack 2"
            currentbuildnumber="6002"
            currentversion="6.0"
            csdversion_hex=dword:00000200
            "$WINE" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "ServerNT" /f
            ;;
        win2k8r2)
            csdversion="Service Pack 1"
            currentbuildnumber="7601"
            currentversion="6.1"
            csdversion_hex=dword:00000100
            "$WINE" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "ServerNT" /f
            ;;
        win8)
            csdversion=""
            currentbuildnumber="9200"
            currentversion="6.2"
            csdversion_hex=dword:00000000
            "$WINE" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "WinNT" /f
            ;;
        win81)
            csdversion=""
            currentbuildnumber="9600"
            currentversion="6.3"
            csdversion_hex=dword:00000000
            "$WINE" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "WinNT" /f
            ;;
        win10)
            csdversion=""
            currentbuildnumber="10240"
            currentversion="10.0"
            csdversion_hex=dword:00000000
            "$WINE" reg add "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" /v ProductType /d "WinNT" /f
            ;;
        *)
            w_die "Invalid Windows version given."
            ;;
    esac

    echo "Setting Windows version to $1"
    cat > "$W_TMP"/set-winver.reg <<_EOF_
REGEDIT4

[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion]
"CSDVersion"="$csdversion"
"CurrentBuildNumber"="$currentbuildnumber"
"CurrentVersion"="$currentversion"

[HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Windows]
"CSDVersion"=$csdversion_hex

_EOF_
    w_try_regedit "$W_TMP_WIN"\\set-winver.reg

    # Prevent a race when calling from another verb
    #w_wineserver -w
}

w_unset_winver()
{
  w_warn "w_unset_winver() is deprecated, use \'w_set_winver default\' instead"
  w_set_winver default
}

# Present app $1 with the Windows personality $2
w_set_app_winver()
{
    w_skip_windows w_set_app_winver && return

    _W_app="$1"
    _W_version="$2"
    echo "Setting $_W_app to $_W_version mode"
    (
    echo REGEDIT4
    echo ""
    echo "[HKEY_CURRENT_USER\\Software\\Wine\\AppDefaults\\$_W_app]"
    echo "\"Version\"=\"$_W_version\""
    ) > "$W_TMP"/set-winver.reg

    w_try_regedit "$W_TMP_WIN"\\set-winver.reg
    rm "$W_TMP"/set-winver.reg
    unset _W_app
}

# Usage: w_compare_wine_version OP VALUE
# Note: currently only -ge and -le are supported,
#       as well as the special case -bn (between)
# Example:
#  if w_compare_wine_version -gt 2.5 ; then
#      ...
#  fi
w_compare_wine_version()
{
    comparison="$1"
    known_wine_val1="$2"
    known_wine_val2="$3"

    case "$comparison" in
        # expected value if the comparison is true
        -bn) _expected_pos_current_wine="2";;
        -ge) _expected_pos_current_wine="2";;
        -le) _expected_pos_current_wine="1";;
        *) w_die "Unsupported comparison. Only -bn, -ge, and -le are supported" ;;
    esac

    # First, check if current wine is equal to either upper or lower wine version:
    case "${_wine_version_stripped}" in
        ${known_wine_val1}|${known_wine_val2}) return 1;;
    esac

    _pos_current_wine="$(printf "%s\\n%s\\n%s" "${known_wine_val1}" "${_wine_version_stripped}" "${known_wine_val2}" | sort -t. -k 1,1n -k 2,2n -k 3,3n | grep -n "^${_wine_version_stripped}\$" | cut -d : -f1)"
    if [ "$_pos_current_wine" = "$_expected_pos_current_wine" ] ; then
        #echo "true: known_wine_version=$2, comparison=$1, stripped wine=$_wine_version_stripped, expected_pos=$_expected_pos_known, pos_known=$_pos_known_wine"
        #echo "Wine version comparison is true"
        return 1
    else
        #echo "false: known_wine_version=$2, comparison=$1, stripped wine=$_wine_version_stripped, expected_pos=$_expected_pos_known, pos_known=$_pos_known_wine"
        #echo "Wine version comparison is false"
        return 0
    fi
}

# Usage: w_wine_version_in range ...
# True if wine version in any of the given ranges
# 'range' can be
#    val1,   (for >= val1)
#    ,val2   (for <= val2)
#    val1,val2 (for >= val1 && <= val2)
w_wine_version_in()
{
    for _W_range; do
        _W_val1=$(echo "$_W_range" | sed 's/,.*//')
        _W_val2=$(echo "$_W_range" | sed 's/.*,//')
        # If in this range, return true
        case $_W_range in
            ,*) w_compare_wine_version -le "$_W_val2"            && unset _W_range _W_val1 _W_val2 && return 0;;
            *,) w_compare_wine_version -ge "$_W_val1"            && unset _W_range _W_val1 _W_val2 && return 0;;
            *)  w_compare_wine_version -bn "$_W_val1" "$_W_val2" && unset _W_range _W_val1 _W_val2 && return 0;;
        esac
    done
    unset _W_range _W_val1 _W_val2
    return 1
}

# Usage: workaround_wine_bug bugnumber [message] [good-wine-version-range ...]
# Returns true and outputs given msg if the workaround needs to be applied.
# For debugging: if you want to skip a bug's workaround, put the bug number in
# the environment variable WINETRICKS_BLACKLIST to disable it.
w_workaround_wine_bug()
{
    if test "$WINE" = ""; then
        echo "No need to work around wine bug $1 on Windows"
        return 1
    fi
    case "$2" in
        [0-9]*) w_die "bug: want message in w_workaround_wine_bug arg 2, got $2" ;;
        "") _W_msg="";;
        *)  _W_msg="-- $2";;
    esac

    # shellcheck disable=SC2086
    if test "$3" && w_wine_version_in $3 $4 $5 $6; then
        echo "Current Wine does not have Wine bug $1, so not applying workaround"
        return 1
    fi

    case "$1" in
        "$WINETRICKS_BLACKLIST")
            echo "Wine bug $1 workaround blacklisted, skipping"
            return 1
            ;;
    esac

    case $LANG in
        da*) w_warn "Arbejder uden om wine-fejl ${1} $_W_msg" ;;
        de*) w_warn "Wine-Fehler ${1} wird umgegangen $_W_msg" ;;
        pl*) w_warn "Obchodzenie błędu w wine ${1} $_W_msg" ;;
        ru*) w_warn "Обход ошибки ${1} $_W_msg" ;;
        uk*) w_warn "Обхід помилки ${1} $_W_msg" ;;
        zh_CN*)   w_warn "绕过 wine bug ${1} $_W_msg" ;;
        zh_TW*|zh_HK*)   w_warn "繞過 wine bug ${1} $_W_msg" ;;
        *)   w_warn "Working around wine bug ${1} $_W_msg" ;;
    esac

    winetricks_stats_log_command "w_workaround_wine_bug-$1"
    return 0
}

# Function for verbs to register themselves so they show up in the menu.
# Example:
# w_metadata wog games \
#   title="World of Goo Demo" \
#   pub="2D Boy" \
#   year="2008" \
#   media="download" \
#   file1="WorldOfGooDemo.1.0.exe"

w_metadata()
{
    case $WINETRICKS_OPT_VERBOSE in
        2) set -x ;;
        *) set +x ;;
    esac

    # shellcheck disable=SC2154
    if test "$installed_exe1" || test "$installed_file1" || test "$publisher" || test "$year"; then
        w_die "bug: stray metadata tags set: somebody forgot a backslash in a w_metadata somewhere.  Run with sh -x to see where."
    fi
    if winetricks_metadata_exists "$1"; then
        w_die "bug: a verb named $1 already exists."
    fi

    _W_md_cmd="$1"
    _W_category="$2"
    file="$WINETRICKS_METADATA/$_W_category/$1.vars"
    shift
    shift
    # Echo arguments to file, with double quotes around the values.
    # Used to use Perl here, but that was too slow on Cygwin.
    for arg; do
        # If _W_wine_not_needed is set, we're a list command that isn't list-installed, and can ignore the installed_* errors:
        case "$arg" in
            installed_exe1=/*)
                if [ -n "$_W_wine_not_needed" ]; then
                    # "_W_wine_not_needed set, no installed_exe1"
                    :
                else
                    w_die "bug: w_metadata $_W_md_cmd has a unix path for installed_exe1, should be a windows path"
                fi
                ;;
            installed_file1=/*)
                if [ -n "$_W_wine_not_needed" ]; then
                    # "_W_wine_not_needed set, no installed_file1"
                    :
                else
                    w_die "bug: w_metadata $_W_md_cmd has a unix path for installed_file1, should be a windows path"
                fi
                ;;
            media=download_manual)
                w_die "bug: verb $_W_md_cmd has media=download_manual, should be manual_download";;
        esac
        # Use longest match when stripping value,
        # and shortest match when stripping name,
        # so descriptions can have embedded equals signs
        # FIXME: backslashes get interpreted here.  This screws up
        # installed_file1 fairly often.  Fortunately, we can use forward
        # slashes in that variable instead of backslashes.
        echo "${arg%%=*}"=\""${arg#*=}"\"
    done > "$file"
    echo category='"'"$_W_category"'"' >> "$file"
    # If the problem described above happens, you'd see errors like this:
    # /tmp/w.dank.4650/metadata/dlls/comctl32.vars: 6: Syntax error: Unterminated quoted string
    # so check for lines that aren't properly quoted.

    # Do sanity check unless running on Cygwin, where it's way too slow.
    case "$W_PLATFORM" in
        windows_cmd)
            ;;
        *)
            if grep '[^"]$' "$file"; then
                w_die "bug: w_metadata $_W_md_cmd corrupt, might need forward slashes?"
            fi
            ;;
    esac
    unset _W_md_cmd

    # Restore verbosity:
    case $WINETRICKS_OPT_VERBOSE in
        1|2) set -x ;;
        *) set +x ;;
    esac
}

# Function for verbs to register their main executable [or, if name is given, other executables]
# Deprecated. No-op for backwards compatibility
w_declare_exe()
{
    w_warn "w_declare_exe is deprecated, now a noop"
}

# Checks that a conflicting verb is not already installed in the prefix
# Usage: w_conflicts verb_to_install conflicting_verbs
w_conflicts()
{
    verb="$1"
    conflicting_verbs="$2"

    for x in $conflicting_verbs; do
        if grep -qw "$x" "$WINEPREFIX/winetricks.log" 2>/dev/null; then
            w_die "error: $verb conflicts with $x, which is already installed. You can run \`$0 --force $verb\` to ignore this check and attempt installation."
        fi
    done
}

# Call a verb, don't let it affect environment
# Hope that subshell passes through exit status
# Usage: w_do_call foo [bar]       (calls load_foo bar)
# Or: w_do_call foo=bar            (also calls load_foo bar)
# Or: w_do_call foo                (calls load_foo)
w_do_call()
{
    (
        # Hack..
        if test "$cmd" = vd; then
            load_vd "$arg"
            _W_status=$?
            test "$W_OPT_NOCLEAN" = 1 || rm -rf "$W_TMP"
            mkdir -p "$W_TMP"
            return $_W_status
        fi

        case "$1" in
            *=*) arg=$(echo "$1" | sed 's/.*=//'); cmd=$(echo "$1" | sed 's/=.*//');;
            *) cmd=$1; arg=$2 ;;
        esac

        # Kludge: use Temp instead of temp to avoid \t expansion in w_try
        # but use temp in Unix path because that's what Wine creates, and having both temp and Temp
        # causes confusion (e.g. makes vc2005trial fail)
        # FIXME: W_TMP is also set in winetricks_set_wineprefix, can we avoid the duplication?
        W_TMP="$W_DRIVE_C/windows/temp/_$1"
        W_TMP_WIN="C:\\windows\\Temp\\_$1"
        test "$W_OPT_NOCLEAN" = 1 || rm -rf "$W_TMP"
        mkdir -p "$W_TMP"

        # Unset all known used metadata values, in case this is a nested call
        unset conflicts installed_file1 installed_exe1

        if winetricks_metadata_exists "$1"; then
            # shellcheck disable=SC1090
            . "$WINETRICKS_METADATA"/*/"${1}.vars"
        elif winetricks_metadata_exists "$cmd"; then
            # shellcheck disable=SC1090
            . "$WINETRICKS_METADATA"/*/"${cmd}.vars"
        elif test "$cmd" = native || test "$cmd" = disabled || test "$cmd" = builtin || test "$cmd" = default; then
            # ugly special case - can't have metadata for these verbs until we allow arbitrary parameters
            w_override_dlls "$cmd" "$arg"
            _W_status=$?
            test "$W_OPT_NOCLEAN" = 1 || rm -rf "$W_TMP"
            mkdir -p "$W_TMP"
            return $_W_status
        else
            w_die "No such verb $1"
        fi

        # If needed, set the app's wineprefix
        case "$W_PLATFORM" in
            windows_cmd|wine_cmd) ;;
            *)
                case "${_W_category}-${WINETRICKS_OPT_SHAREDPREFIX}" in
                    apps-0|benchmarks-0|games-0) winetricks_set_wineprefix "$cmd";;
                    *) winetricks_set_wineprefix "$_W_prefix_name";;
                esac
                # If it's a new wineprefix, give it metadata
                if test ! -f "$WINEPREFIX"/wrapper.cfg; then
                    echo ww_name=\""$title"\" > "$WINEPREFIX"/wrapper.cfg
                fi
            ;;
        esac

        test "$W_OPT_NOCLEAN" = 1 || rm -rf "$W_TMP"
        mkdir -p "$W_TMP"

        # Don't install if a conflicting verb is already installed:
        # shellcheck disable=SC2154
        if test "$WINETRICKS_FORCE" != 1 && test "$conflicts" && test -f "$WINEPREFIX/winetricks.log"; then
            for x in $conflicts; do
                w_conflicts "$1" "$x"
            done
        fi

        # Allow verifying a verb separately from installing it
        if test "$WINETRICKS_VERIFY" = 1 && winetricks_is_installed "$1" && test -z "$WINETRICKS_FORCE"; then
            echo "$1 is already installed. --force wasn't given, --verify was, so re-verifying."
            winetricks_verify
            return 0
        fi

        # Don't install if already installed
        if test "$WINETRICKS_FORCE" != 1 && winetricks_is_installed "$1"; then
            echo "$1 already installed, skipping"
            return 0
        fi

        # We'd like to get rid of W_PACKAGE, but for now, just set it as late as possible.
        W_PACKAGE=$1
        w_try "load_$cmd" "$arg"
        winetricks_stats_log_command "$@"

        # User-specific postinstall hook.
        # Source it so the script can call w_download() if needed.
        postfile="$WINETRICKS_POST/$1/$1-postinstall.sh"
        if test -f "$postfile"; then
            chmod +x "$postfile"
            # shellcheck disable=SC1090
            . "$postfile"
        fi

        # Verify install
        if test "$installed_exe1" || test "$installed_file1"; then
            if ! winetricks_is_installed "$1"; then
                w_die "$1 install completed, but installed file $_W_file_unix not found"
            fi
        fi

        # If the user specified --verify, also run GUI tests:
        if test "$WINETRICKS_VERIFY" = 1; then
            winetricks_verify
        fi

        # Clean up after this verb
        test "$W_OPT_NOCLEAN" = 1 || rm -rf "$W_TMP"
        mkdir -p "$W_TMP"

        # Reset whether use of user mount tool
        unset W_USE_USERMOUNT

        # Calling subshell must explicitly propagate error code with exit $?
    ) || exit $?
}

# If you want to check exit status yourself, use w_do_call
w_call()
{
    w_try w_do_call "$@"
}

w_backup_reg_file()
{
    W_reg_file=$1

    w_get_sha256sum "$W_reg_file"

    w_try cp "$W_reg_file" "$W_TMP_EARLY/_reg_$(echo "$_W_gotsha256sum" | cut -c1-8)"_$$.reg

    unset W_reg_file _W_gotsha256sum
}

w_register_font()
{
    W_file=$1
    shift
    W_font=$1

    case $(echo "$W_file" | tr "[:upper:]" "[:lower:]") in
        *.ttf|*.ttc) W_font="$W_font (TrueType)";;
    esac

    # Kludge: use _r to avoid \r expansion in w_try
    cat > "$W_TMP"/_register-font.reg <<_EOF_
REGEDIT4

[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts]
"$W_font"="$W_file"
_EOF_
    # too verbose
    w_try_regedit "$W_TMP_WIN"\\_register-font.reg
    w_backup_reg_file "$W_TMP"/_register-font.reg

    # Wine also updates the win9x fonts key, so let's do that, too
    cat > "$W_TMP"/_register-font.reg <<_EOF_
REGEDIT4

[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Fonts]
"$W_font"="$W_file"
_EOF_
    w_try_regedit "$W_TMP_WIN"\\_register-font.reg
    w_backup_reg_file "$W_TMP"/_register-font.reg

    unset W_file W_font
}

# Note: we use UTF-16 (little endian) in .reg file for native (non-English) font names.
w_register_font_replacement()
{
    _W_alias=$1
    shift
    _W_font=$1
    # UTF-16 BOM (U+FEFF, "0xEF 0xBB 0xBF" in UTF-8)
    printf "\357\273\277" | iconv -f UTF-8 -t UTF-16LE > "$W_TMP"/_register-font-replacements.reg
    # Kludge: use _r to avoid \r expansion in w_try
    iconv -f UTF-8 -t UTF-16LE >> "$W_TMP"/_register-font-replacements.reg <<_EOF_
REGEDIT4

[HKEY_CURRENT_USER\\Software\\Wine\\Fonts\\Replacements]
"$_W_alias"="$_W_font"
_EOF_
    w_try_regedit "$W_TMP_WIN"\\_register-font-replacements.reg

    w_backup_reg_file "$W_TMP"/_register-font-replacements.reg

    unset _W_alias _W_font
}

w_append_path()
{
    # Prepend $1 to the Windows path in the registry.
    # Use printf %s to avoid interpreting backslashes.
    # 2/4 backslashes, not 4/8, see https://github.com/Winetricks/winetricks/issues/932
    _W_NEW_PATH="$(printf %s "$1" | sed 's,\\,\\\\,g')"
    _W_WIN_PATH="$(w_expand_env PATH | sed 's,\\,\\\\,g')"

    # FIXME: OS X? https://github.com/Winetricks/winetricks/issues/697
    sed 's/$/\r/' > "$W_TMP"/path.reg <<_EOF_
REGEDIT4

[HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\Environment]
"PATH"="$_W_NEW_PATH;$_W_WIN_PATH"
_EOF_

    w_try_regedit "$W_TMP_WIN"\\path.reg
    rm -f "$W_TMP"/path.reg
    unset _W_NEW_PATH _W_WIN_PATH
}

#---- Private Functions ----

# Determines downloader to use, etc.
# I.e., things common to w_download_to(), winetricks_download_to_stdout(), and winetricks_stats_report())
winetricks_download_setup()
{
    # shellcheck disable=SC2104
    case "${WINETRICKS_DOWNLOADER}" in
        aria2c|curl|wget|fetch) : ;;
        "") if [ -x "$(command -v aria2c 2>/dev/null)" ] ; then
                WINETRICKS_DOWNLOADER="aria2c"
            elif [ -x "$(command -v wget 2>/dev/null)" ] ; then
                WINETRICKS_DOWNLOADER="wget"
            elif [ -x "$(command -v curl 2>/dev/null)" ] ; then
                WINETRICKS_DOWNLOADER="curl"
            elif [ -x "$(command -v fetch 2>/dev/null)" ] ; then
                WINETRICKS_DOWNLOADER="fetch"
            else
                w_die "Please install wget or aria2c (or, if those aren't available, curl)"
            fi
            ;;
        *) w_die "Invalid value ${WINETRICKS_DOWNLOADER} given for WINETRICKS_DOWNLOADER. Possible values: aria2c, curl, wget, fetch"
    esac

    # Common values for aria2c/curl/fetch/wget
    # Number of retry attempts (not supported by fetch):
    WINETRICKS_DOWNLOADER_RETRIES=${WINETRICKS_DOWNLOADER_RETRIES:-3}
    # Connection timeout time (in seconds):
    WINETRICKS_DOWNLOADER_TIMEOUT=${WINETRICKS_DOWNLOADER_TIMEOUT:-15}

    case "$WINETRICKS_OPT_TORIFY" in
        1) torify=torify
            # torify needs --async-dns=false, see https://github.com/tatsuhiro-t/aria2/issues/613
            aria2c_torify_opts="--async-dns=false"
            if [ ! -x "$(command -v torify 2>/dev/null)" ]; then
                w_die "--torify was used, but torify is not installed, please install it." ; exit 1
            fi ;;
        *) torify=
            aria2c_torify_opts="" ;;
    esac
}


winetricks_dl_url_to_stdout()
{
    winetricks_download_setup

    # Not using w_try here as it adds extra output, breaking things.
    # FIXME: add a w_try_quiet() wrapper around w_try() that doesn't print the
    # Executing ... stuff, but still does error checking
    if [ "${WINETRICKS_DOWNLOADER}" = "wget" ] ; then
        $torify wget -q -O - --timeout "${WINETRICKS_DOWNLOADER_TIMEOUT}" \
            --tries "$WINETRICKS_DOWNLOADER_RETRIES" "$1"
    elif [ "${WINETRICKS_DOWNLOADER}" = "curl" ] ; then
        $torify curl -s --connect-timeout "${WINETRICKS_DOWNLOADER_TIMEOUT}" \
               --retry "$WINETRICKS_DOWNLOADER_RETRIES" "$1"
    elif [ "${WINETRICKS_DOWNLOADER}" = "aria2c" ] ; then
        # aria2c doesn't have support downloading to stdout:
        # https://github.com/aria2/aria2/issues/190
        # So instead, download to a temporary directory and cat the file:
        stdout_tmpfile="${W_TMP_EARLY}/stdout.tmp"

        if [ -e "${stdout_tmpfile}" ] ; then
            rm "${stdout_tmpfile}"
        fi
                $torify aria2c \
                $aria2c_torify_opts \
                --continue \
                --daemon=false \
                --dir="${W_TMP_EARLY}" \
                --enable-rpc=false \
                --input-file='' \
                --max-connection-per-server=5 \
                --out="stdout.tmp" \
                --save-session='' \
                --stream-piece-selector=geom \
                --connect-timeout="${WINETRICKS_DOWNLOADER_TIMEOUT}" \
                --max-tries="$WINETRICKS_DOWNLOADER_RETRIES" \
                "$1" > /dev/null
        cat "${stdout_tmpfile}"
        rm "${stdout_tmpfile}"
    elif [ "${WINETRICKS_DOWNLOADER}" = "fetch" ] ; then
        # fetch does not support retry count
        $torify fetch -o - -T "${WINETRICKS_DOWNLOADER_TIMEOUT}" "$1" 2>/dev/null
    else
        w_die "Please install aria2c, curl, or wget"
    fi
}

winetricks_dl_warning() {
    case $LANG in
        ru*) _W_countrymsg="Скрипт определил, что ваш IP-адрес принадлежит России. Если во время загрузки файлов вы увидите ошибки несоответствия сертификата, перезапустите скрипт с опцией '--torify' или скачайте файлы вручную, например, используя VPN." ;;
        pl*) _W_countrymsg="Wykryto, że twój adres IP należy do Rosji. W wypadku problemów z pobieraniem, uruchom z parametrem '--torify' lub pobierz plik manualnie, np. z użyciem VPN." ;;
        *)  _W_countrymsg="Your IP address has been determined to belong to Russia. If you encounter a certificate error while downloading, please relaunch with the '--torify' option, or download files manually, for instance using VPN." ;;
    esac

    # Lookup own country via IP address only once (i.e. don't run this function for every download invocation)
    if [ -z "$W_COUNTRY" ] ; then
        W_COUNTRY="$(winetricks_dl_url_to_stdout "https://ipinfo.io/$(winetricks_dl_url_to_stdout "https://ipinfo.io/ip")" | awk -F '"' '/country/{print $4}')"
        export W_COUNTRY

        if [ -z "$W_COUNTRY" ] ; then
            export W_COUNTRY="unknown"
        fi
    fi

    # TODO: Resolve a full country name via https://github.com/umpirsky/country-list/tree/master/data
    case "$W_COUNTRY" in
        "RU") w_warn "$_W_countrymsg" ;;
        *) : ;;
    esac
}

winetricks_get_sha256sum_prog() {
    # Linux/Solaris:
    if [ -x "$(command -v sha256sum 2>/dev/null)" ] ; then
        WINETRICKS_SHA256SUM="sha256sum"
    # FreeBSD/NetBSD:
    elif [ -x "$(command -v sha256 2>/dev/null)" ] ; then
        WINETRICKS_SHA256SUM="sha256"
    # OSX (10.6+), 10.5 doesn't support at all: https://stackoverflow.com/questions/7500691/rvm-sha256sum-nor-shasum-found
    elif [ -x "$(command -v shasum 2>/dev/null)" ] ; then
        WINETRICKS_SHA256SUM="shasum -a 256"
    else
        w_die "No sha256um utility available."
    fi
}

winetricks_get_platform()
{
    if [ "${OS}" = "Windows_NT" ]; then
        if [ -n "${WINELOADERNOEXEC}" ]; then
            # Windows/Cygwin
            export W_PLATFORM="windows_cmd"
        else
            # wineconsole/cmd under wine
            export W_PLATFORM="wine_cmd"
        fi
    else
        # Normal Unix shell
        export W_PLATFORM="wine"
    fi
}

winetricks_print_version()
{
    # Normally done by winetricks_init, but we don't want to set up the WINEPREFIX
    # just to get the winetricks version:

    winetricks_get_sha256sum_prog

    w_get_sha256sum "$0"
    echo "$WINETRICKS_VERSION - sha256sum: $_W_gotsha256sum"
}

# Run a small wine command for internal use
# Handy place to put small workarounds
winetricks_early_wine()
{
    # The sed works around https://bugs.winehq.org/show_bug.cgi?id=25838
    # which unfortunately got released in wine-1.3.12
    # We would like to use DISPLAY= to prevent virtual desktops from
    # popping up, but that causes AutoHotKey's tray icon to not show up.
    # We used to use WINEDLLOVERRIDES=mshtml= here to suppress the Gecko
    # autoinstall, but that yielded wineprefixes that *never* autoinstalled
    # Gecko (winezeug bug 223).
    # The tr removes carriage returns so expanded variables don't have crud on the end
    # The grep works around using new wineprefixes with old wine
    WINEDEBUG=-all "$WINE" "$@" 2> "$W_TMP_EARLY"/early_wine.err.txt | ( sed 's/.*1h.=//' | tr -d '\r' | grep -v -e "Module not found" -e "Could not load wine-gecko" || true)
}

# Wrapper around winetricks_early_wine()
# Same idea, but use $WINE_ARCH, i.e., always use wine64 for 64-bit prefixes
# Currently only used by w_expand_env()
winetricks_early_wine_arch()
{
    WINE="$WINE_ARCH" winetricks_early_wine "$@"
}

winetricks_detect_gui()
{
    if test -x "$(command -v zenity 2>/dev/null)"; then
        WINETRICKS_GUI=zenity
        WINETRICKS_GUI_VERSION="$(zenity --version)"
        WINETRICKS_MENU_HEIGHT=500
        WINETRICKS_MENU_WIDTH=1010
    elif test -x "$(command -v kdialog 2>/dev/null)"; then
        echo "Zenity not found!  Using kdialog as poor substitute."
        WINETRICKS_GUI=kdialog
        WINETRICKS_GUI_VERSION="$(kdialog --version)"
    else
        echo "No arguments given, so tried to start GUI, but zenity not found."
        echo "Please install zenity if you want a graphical interface, or "
        echo "run with --help for more options."
        exit 1
    fi

    # Print zenity/dialog version info for debugging:
    if [ -z "$WINETRICKS_SUPER_QUIET" ] ; then
       echo "winetricks GUI enabled, using $WINETRICKS_GUI $WINETRICKS_GUI_VERSION"
    fi
}

# Detect which sudo to use
winetricks_detect_sudo()
{
    WINETRICKS_SUDO=sudo
    if test "$WINETRICKS_GUI" = "none"; then
        return
    fi

    if test x"$DISPLAY" != x""; then
        # This should be the default option because some of GUI sudo programs are unmaintained
        # See https://github.com/Winetricks/winetricks/issues/912
        if test -x "$(command -v pkexec 2>/dev/null)"; then
            # Maintained and recommended, part of Polkit, desktop-independent
            # Usage: pkexec command ...
            WINETRICKS_SUDO=pkexec
        # Austin said "gksu*/kdesu* should stay (at least for a while)" in Feb 2018
        # See https://github.com/Winetricks/winetricks/pull/915#issuecomment-362984379
        elif test -x "$(command -v gksudo 2>/dev/null)"; then
            # Unmaintained [2009], part of gksu
            # Usage: gksudo "command ..."
            WINETRICKS_SUDO=gksudo
        elif test -x "$(command -v kdesudo 2>/dev/null)"; then
            # Unmaintained [2015] (latest is for KDE4, no KF5 version available)
            # https://cgit.kde.org/kdesudo.git/
            # Usage: kdesudo "command ..."
            WINETRICKS_SUDO=kdesudo
        # fall back to the su versions if sudo isn't available (Fedora, etc.):
        elif test -x "$(command -v gksu 2>/dev/null)"; then
            # Unmaintained [2009]
            # Usage: gksu "command ..."
            WINETRICKS_SUDO=gksu
        elif test -x "$(command -v kdesu 2>/dev/null)"; then
            # Maintained, KF5 version available
            # https://cgit.kde.org/kdesu.git/
            # Usage: kdesu -c "command ..."
            WINETRICKS_SUDO=kdesu
        fi
    fi
}

# Detect which iso mount tool to use
winetricks_detect_iso_mount()
{
    if test -x "$(command -v fuseiso 2>/dev/null)"; then
        # File/dir names are converted to lowercase
        WINETRICKS_ISO_MOUNT=fuseiso
    elif test -x "$(command -v archivemount 2>/dev/null)"; then
        # File/dir names may be uppercase and we may need
        # case-insensitive operations
        #   e.g. w_try "$WINE" cmd /c "copy $W_ISO_MOUNT_LETTER:\\DOC.PDF C:\\doc.pdf"
        # This tool had path issue in 0.8.8 or older versions
        #   e.g. office2013pro works in 0.8.9 or later but doesn't work in 0.8.8
        WINETRICKS_ISO_MOUNT=archivemount
    elif test -x "$(command -v hdiutil 2>/dev/null)"; then
        # File/dir names may be uppercase (same as archivemount)
        WINETRICKS_ISO_MOUNT=hdiutil
    else
        WINETRICKS_ISO_MOUNT=none
    fi
    # Notes about other tools:
    #   fuseiso9660: may append ";1" to filenames
    #   unar: the drive icon is not "optical drive + disc" in Wine Explorer
    #         and "wine eject" command fails
}

winetricks_get_prefix_var()
{
    (
        # shellcheck disable=SC1090
        . "$W_PREFIXES_ROOT/$p/wrapper.cfg"

        # The cryptic sed is there to turn ' into '\''
        # shellcheck disable=SC1117
        eval echo \$ww_"$1" | sed "s/'/'\\\''/"
    )
}

# Display prefix menu, get which wineprefix the user wants to work with
winetricks_prefixmenu()
{
    case $LANG in
        ru*) _W_msg_title="Winetricks - выберите путь wine (wineprefix)"
             _W_msg_body='Что вы хотите сделать?'
             _W_msg_default="Выберите путь для wine по умолчанию"
             _W_msg_mkprefix="Создать новый путь wine"
             _W_msg_unattended0="Отключить автоматическую установку"
             _W_msg_unattended1="Включить автоматическую установку"
             _W_msg_help="Просмотр справки (в веб-браузере)"
             ;;
        uk*) _W_msg_title="Winetricks - виберіть wineprefix"
             _W_msg_body='Що Ви хочете зробити?'
             _W_msg_default="Вибрати wineprefix за замовчуванням"
             _W_msg_mkprefix="створити новий wineprefix"
             _W_msg_unattended0="Вимкнути автоматичне встановлення"
             _W_msg_unattended1="Увімкнути автоматичне встановлення"
             _W_msg_help="Переглянути довідку"
             ;;
        zh_CN*)   _W_msg_title="Winetricks - 选择一个 Wine 容器"
             _W_msg_body='您想要做什么？'
             _W_msg_default="选择默认的 Wine 容器"
             _W_msg_mkprefix="创建新的 Wine 容器"
             _W_msg_unattended0="禁用静默安装"
             _W_msg_unattended1="启用静默安装"
             _W_msg_help="查看帮助"
             ;;
        zh_TW*|zh_HK*)   _W_msg_title="Winetricks - 選取一個 Wine 容器"
             _W_msg_body='您想要做什麼？'
             _W_msg_default="選取預設的 Wine 容器"
             _W_msg_mkprefix="建立新的 Wine 容器"
             _W_msg_unattended0="禁用靜默安裝"
             _W_msg_unattended1="啟用靜默安裝"
             _W_msg_help="檢視輔助說明"
             ;;
        de*) _W_msg_title="Winetricks - wineprefix auswählen"
             _W_msg_body='Was möchten Sie tun?'
             _W_msg_default="Standard wineprefix auswählen"
             _W_msg_mkprefix="Neuen wineprefix erstellen"
             _W_msg_unattended0="Automatische Installation deaktivieren"
             _W_msg_unattended1="Automatische Installation aktivieren"
             _W_msg_help="Hilfe anzeigen"
             ;;
        pl*) _W_msg_title="Winetricks - wybierz prefiks Wine"
             _W_msg_body='Co chcesz zrobić?'
             _W_msg_default="Wybrać domyślny prefiks Wine"
             _W_msg_mkprefix="Stwórz nowy prefiks Wine"
             _W_msg_unattended0="Wyłącz cichą instalację"
             _W_msg_unattended1="Włącz cichą instalację"
             _W_msg_help="Wyświetl pomoc"
             ;;
        *)   _W_msg_title="Winetricks - choose a wineprefix"
             _W_msg_body='What do you want to do?'
             _W_msg_default="Select the default wineprefix"
             _W_msg_mkprefix="Create new wineprefix"
             _W_msg_unattended0="Disable silent install"
             _W_msg_unattended1="Enable silent install"
             _W_msg_help="View help"
             ;;
    esac
    case "$W_OPT_UNATTENDED" in
        1) _W_cmd_unattended=attended; _W_msg_unattended="$_W_msg_unattended0" ;;
        *) _W_cmd_unattended=unattended; _W_msg_unattended="$_W_msg_unattended1" ;;
    esac

    case $WINETRICKS_GUI in
        zenity)
            printf %s "zenity \
                --title '$_W_msg_title' \
                --text '$_W_msg_body' \
                --list \
                --radiolist \
                --column '' \
                --column '' \
                --column '' \
                --height $WINETRICKS_MENU_HEIGHT \
                --width $WINETRICKS_MENU_WIDTH \
                --hide-column 2 \
                FALSE help       '$_W_msg_help' \
                TRUE  main       '$_W_msg_default' \
                FALSE mkprefix   '$_W_msg_mkprefix' \
                " \
                > "$WINETRICKS_WORKDIR"/zenity.sh

            if ls -d "$W_PREFIXES_ROOT"/*/dosdevices > /dev/null 2>&1; then
                for prefix in "$W_PREFIXES_ROOT"/*/dosdevices; do
                    q="${prefix%%/dosdevices}"
                    p="${q##*/}"
                    if test -f "$W_PREFIXES_ROOT/$p/wrapper.cfg"; then
                        _W_msg_name="$p ($(winetricks_get_prefix_var name))"
                    else
                        _W_msg_name="$p"
                    fi
                case $LANG in
                    zh_CN*) printf %s " FALSE prefix='$p' '选择管理 $_W_msg_name' " ;;
                    zh_TW*|zh_HK*) printf %s " FALSE prefix='$p' '選擇管理 $_W_msg_name' " ;;
                    de*) printf %s " FALSE prefix='$p' '$_W_msg_name auswählen' " ;;
                    pl*) printf %s " FALSE prefix='$p' 'Wybierz $_W_msg_name' " ;;
                    *) printf %s " FALSE prefix='$p' 'Select $_W_msg_name' " ;;
                esac
                done >> "$WINETRICKS_WORKDIR"/zenity.sh
            fi
            printf %s " FALSE $_W_cmd_unattended '$_W_msg_unattended'" >> "$WINETRICKS_WORKDIR"/zenity.sh

            sh "$WINETRICKS_WORKDIR"/zenity.sh | tr '|' ' '
            ;;

        kdialog)
            (
            printf %s "kdialog \
                --geometry 600x400+100+100 \
                --title '$_W_msg_title' \
                --separate-output \
                --radiolist '$_W_msg_body' \
                help       '$_W_msg_help'       off \
                main       '$_W_msg_default'    on  \
                mkprefix   '$_W_msg_mkprefix'   off \
                "
            if ls -d "$W_PREFIXES_ROOT"/*/dosdevices > /dev/null 2>&1; then
                for prefix in "$W_PREFIXES_ROOT"/*/dosdevices; do
                    q="${prefix%%/dosdevices}"
                    p="${q##*/}"
                    if test -f "$W_PREFIXES_ROOT/$p/wrapper.cfg"; then
                        _W_msg_name="$p ($(winetricks_get_prefix_var name))"
                    else
                        _W_msg_name="$p"
                    fi
                    printf %s "prefix='$p' 'Select $_W_msg_name' off "
                done
            fi
            printf %s " $_W_cmd_unattended '$_W_msg_unattended' off"
            ) > "$WINETRICKS_WORKDIR"/kdialog.sh
            sh "$WINETRICKS_WORKDIR"/kdialog.sh
            ;;
    esac
    unset _W_msg_help _W_msg_body _W_msg_title _W_msg_new _W_msg_default _W_msg_name
}

# Graphically create new custom wineprefix.
# This returns two verbs: arch and prefix, e.g. "arch=32 prefix=test".
winetricks_mkprefixmenu()
{
    case $LANG in
        # TODO: translate to other languages
        de)  _W_msg_title="Winetricks - Neues Wineprefix erstellen"
             _W_msg_name="Name"
             _W_msg_arch="Architektur"
             ;;
        *)   _W_msg_title="Winetricks - create new wineprefix"
             _W_msg_name="Name"
             _W_msg_arch="Architecture"
             ;;
    esac

    case $WINETRICKS_GUI in
        zenity)
            $WINETRICKS_GUI --forms --text="" --title "$_W_msg_title" \
                --add-combo="$_W_msg_arch" --combo-values=32\|64 \
                --add-entry="$_W_msg_name" \
                | sed -e 's/^\s*|/64|/' -e 's/^/arch=/' -e 's/|/ prefix=/'
            ;;
        kdialog)
            $WINETRICKS_GUI --title="$_W_msg_title" \
                --radiolist="$_W_msg_arch" 32 32bit off 64 64bit on \
                | sed -e 's/^$/64/' -e 's/^/arch=/'
            $WINETRICKS_GUI --title="$_W_msg_title" --inputbox="$_W_msg_name" \
                | sed -e 's/^/prefix=/'
            ;;
    esac

    unset _W_msg_title _W_msg_name _W_msg_arch
}

# Display main menu, get which submenu the user wants
winetricks_mainmenu()
{
    case $LANG in
        da*) _W_msg_title="Vælg en pakke-kategori - Nuværende præfiks er \"$WINEPREFIX\""
             _W_msg_body='Hvad ønsker du at gøre?'
             _W_msg_dlls="Install a Windows DLL"
             _W_msg_fonts='Install a font'
             _W_msg_settings='Change Wine settings'
             _W_msg_winecfg='Run winecfg'
             _W_msg_regedit='Run regedit'
             _W_msg_taskmgr='Run taskmgr'
             _W_msg_explorer='Run explorer'
             _W_msg_uninstaller='Run uninstaller'
             _W_msg_shell='Run a commandline shell (for debugging)'
             _W_msg_folder='Browse files'
             _W_msg_annihilate="Delete ALL DATA AND APPLICATIONS INSIDE THIS WINEPREFIX"
             ;;
        de*) _W_msg_title="Pakettyp auswählen - Aktueller Präfix ist \"$WINEPREFIX\""
             _W_msg_body='Was möchten Sie tun?'
             _W_msg_dlls="Windows-DLL installieren"
             _W_msg_fonts='Schriftart installieren'
             _W_msg_settings='Wine Einstellungen ändern'
             _W_msg_winecfg='winecfg starten'
             _W_msg_regedit='regedit starten'
             _W_msg_taskmgr='taskmgr starten'
             _W_msg_explorer='explorer starten'
             _W_msg_uninstaller='uninstaller starten'
             _W_msg_shell='Eine Kommandozeile zum debuggen starten'
             _W_msg_folder='Ordner durchsuchen'
             _W_msg_annihilate="ALLE DATEIEN UND PROGRAMME IN DIESEM WINEPREFIX Löschen"
             ;;
        pl*) _W_msg_title="Winetricks - obecny prefiks to \"$WINEPREFIX\""
             _W_msg_body='Co chcesz zrobić w tym prefiksie?'
             _W_msg_dlls="Zainstalować windowsową bibliotekę DLL lub komponent"
             _W_msg_fonts='Zainstalować czcionkę'
             _W_msg_settings='Zmienić ustawienia'
             _W_msg_winecfg='Uruchomić winecfg'
             _W_msg_regedit='Uruchomić edytor rejestru'
             _W_msg_taskmgr='Uruchomić menedżer zadań'
             _W_msg_explorer='Uruchomić explorer'
             _W_msg_uninstaller='Uruchomić program odinstalowujący'
             _W_msg_shell='Uruchomić powłokę wiersza poleceń (dla debugowania)'
             _W_msg_folder='Przeglądać pliki'
             _W_msg_annihilate="Usuńąć WSZYSTKIE DANE I APLIKACJE WEWNĄTRZ TEGO PREFIKSU WINE"
             ;;
        ru*) _W_msg_title="Winetricks - текущий путь для wine (wineprefix) \"$WINEPREFIX\""
             _W_msg_body='Что вы хотите сделать с этим wineprefix?'
             _W_msg_dlls="Установить библиотеку DLL или компонент Windows"
             _W_msg_fonts='Установить шрифт'
             _W_msg_settings='Поменять настройки'
             _W_msg_winecfg='Запустить winecfg (редактор настроек wine)'
             _W_msg_regedit='Запустить regedit (редактор реестра)'
             _W_msg_taskmgr='Запустить taskmgr (менеджер задач)'
             _W_msg_explorer='Запустить explorer'
             _W_msg_uninstaller='Запустить uninstaller (деинсталлятор)'
             _W_msg_shell='Запустить графический терминал (для отладки)'
             _W_msg_folder='Проводник файлов'
             _W_msg_annihilate="Удалить ВСЕ ДАННЫЕ И ПРИЛОЖЕНИЯ В ЭТОМ WINEPREFIX"
             ;;
        uk*) _W_msg_title="Winetricks - поточний prefix \"$WINEPREFIX\""
             _W_msg_body='Що Ви хочете зробити для цього wineprefix?'
             _W_msg_dlls="Встановити Windows DLL чи компонент(и)"
             _W_msg_fonts='Встановити шрифт'
             _W_msg_settings='Змінити налаштування'
             _W_msg_winecfg='Запустити winecfg'
             _W_msg_regedit='Запустити regedit'
             _W_msg_taskmgr='Запустити taskmgr'
             _W_msg_explorer='Запустити explorer'
             _W_msg_uninstaller='Встановлення/видалення програм'
             _W_msg_shell='Запуск командної оболонки (для налагодження)'
             _W_msg_folder='Перегляд файлів'
             _W_msg_annihilate="Видалити УСІ ДАНІ ТА ПРОГРАМИ З ЦЬОГО WINEPREFIX"
             ;;
        zh_CN*)   _W_msg_title="Winetricks - 当前容器路径是 \"$WINEPREFIX\""
             _W_msg_body='管理当前容器'
             _W_msg_dlls="安装 Windows DLL 或组件"
             _W_msg_fonts='安装字体'
             _W_msg_settings='修改设置'
             _W_msg_winecfg='运行 Wine 配置程序'
             _W_msg_regedit='运行注册表'
             _W_msg_taskmgr='运行任务管理器'
             _W_msg_explorer='运行资源管理器'
             _W_msg_uninstaller='运行卸载程序'
             _W_msg_shell='运行命令提示窗口 (作为调试)'
             _W_msg_folder='浏览容器中的文件'
             _W_msg_annihilate="删除容器中所有数据和应用程序"
             ;;
        zh_TW*|zh_HK*)   _W_msg_title="Winetricks - 目前容器路徑是 \"$WINEPREFIX\""
             _W_msg_body='管理目前容器'
             _W_msg_dlls="安裝 Windows DLL 或套件"
             _W_msg_fonts='安裝字型'
             _W_msg_settings='修改設定'
             _W_msg_winecfg='執行 Wine 設定程式'
             _W_msg_regedit='執行登錄編輯程式'
             _W_msg_taskmgr='執行工作管理員'
             _W_msg_explorer='執行檔案總管'
             _W_msg_uninstaller='執行解除安裝程式'
             _W_msg_shell='執行命令提示視窗 (作為偵錯)'
             _W_msg_folder='瀏覽容器中的檔案'
             _W_msg_annihilate="刪除容器中所有資料和應用程式"
             ;;
        *)   _W_msg_title="Winetricks - current prefix is \"$WINEPREFIX\""
             _W_msg_body='What would you like to do to this wineprefix?'
             _W_msg_dlls="Install a Windows DLL or component"
             _W_msg_fonts='Install a font'
             _W_msg_settings='Change settings'
             _W_msg_winecfg='Run winecfg'
             _W_msg_regedit='Run regedit'
             _W_msg_taskmgr='Run taskmgr'
             _W_msg_explorer='Run explorer'
             _W_msg_uninstaller='Run uninstaller'
             _W_msg_shell='Run a commandline shell (for debugging)'
             _W_msg_folder='Browse files'
             _W_msg_annihilate="Delete ALL DATA AND APPLICATIONS INSIDE THIS WINEPREFIX"
             ;;
    esac

    case $WINETRICKS_GUI in
        zenity)
            (
                printf %s "zenity \
                    --title '$_W_msg_title' \
                    --text '$_W_msg_body' \
                    --list \
                    --radiolist \
                    --column '' \
                    --column '' \
                    --column '' \
                    --height $WINETRICKS_MENU_HEIGHT \
                    --width $WINETRICKS_MENU_WIDTH \
                    --hide-column 2 \
                    FALSE dlls        '$_W_msg_dlls' \
                    FALSE fonts       '$_W_msg_fonts' \
                    FALSE settings    '$_W_msg_settings' \
                    FALSE winecfg     '$_W_msg_winecfg' \
                    FALSE regedit     '$_W_msg_regedit' \
                    FALSE taskmgr     '$_W_msg_taskmgr' \
                    FALSE explorer    '$_W_msg_explorer' \
                    FALSE uninstaller '$_W_msg_uninstaller' \
                    FALSE shell       '$_W_msg_shell' \
                    FALSE folder      '$_W_msg_folder' \
                    FALSE annihilate  '$_W_msg_annihilate' \
                 "
            ) > "$WINETRICKS_WORKDIR"/zenity.sh

            sh "$WINETRICKS_WORKDIR"/zenity.sh | tr '|' ' '
            ;;

        kdialog)
            $WINETRICKS_GUI --geometry 600x400+100+100 \
                    --title "$_W_msg_title" \
                    --separate-output \
                    --radiolist \
                    "$_W_msg_body"\
                    dlls        "$_W_msg_dlls" off \
                    fonts       "$_W_msg_fonts" off \
                    settings    "$_W_msg_settings" off \
                    winecfg     "$_W_msg_winecfg" off \
                    regedit     "$_W_msg_regedit" off \
                    taskmgr     "$_W_msg_taskmgr" off \
                    explorer    "$_W_msg_explorer" off \
                    uninstaller "$_W_msg_uninstaller" off \
                    shell       "$_W_msg_shell" off \
                    folder      "$_W_msg_folder" off \
                    annihilate  "$_W_msg_annihilate" off \
                    $_W_cmd_unattended "$_W_msg_unattended" off \

            ;;
    esac
    unset _W_msg_body _W_msg_title _W_msg_dlls _W_msg_settings
}

winetricks_settings_menu()
{
    # FIXME: these translations should really be centralized/reused:
    case $LANG in
        da*) _W_msg_title="Vælg en pakke - Nuværende præfiks er \"$WINEPREFIX\""
             _W_msg_body='Which settings would you like to change?'
             ;;
        de*) _W_msg_title="Winetricks - Aktueller Präfix ist \"$WINEPREFIX\""
             _W_msg_body='Welche Einstellungen möchten Sie ändern?'
             ;;
        pl*) _W_msg_title="Winetricks - obecny prefiks to \"$WINEPREFIX\""
             _W_msg_body='Jakie ustawienia chcesz zmienić?'
             ;;
        ru*) _W_msg_title="Winetricks - текущий путь wine (wineprefix) \"$WINEPREFIX\""
             _W_msg_body='Какие настройки вы хотите изменить?'
             ;;
        uk*) _W_msg_title="Winetricks - поточний prefix \"$WINEPREFIX\""
             _W_msg_body='Які налаштування Ви хочете змінити?'
             ;;
        zh_CN*)   _W_msg_title="Winetricks - 当前容器路径是 \"$WINEPREFIX\""
             _W_msg_body='您想要更改哪项设置？'
             ;;
        zh_TW*|zh_HK*)   _W_msg_title="Winetricks - 目前容器路徑是 \"$WINEPREFIX\""
             _W_msg_body='您想要變更哪項設定？'
             ;;
        *)   _W_msg_title="Winetricks - current prefix is \"$WINEPREFIX\""
             _W_msg_body='Which settings would you like to change?'
             ;;
    esac

    case $WINETRICKS_GUI in
        zenity)
            case $LANG in
                da*) printf %s "zenity \
                        --title '$_W_msg_title' \
                        --text '$_W_msg_body' \
                        --list \
                        --checklist \
                        --column '' \
                        --column Pakke \
                        --column Navn \
                        --height $WINETRICKS_MENU_HEIGHT \
                        --width $WINETRICKS_MENU_WIDTH \
                        "
                    ;;
                de*) printf %s "zenity \
                        --title '$_W_msg_title' \
                        --text '$_W_msg_body' \
                        --list \
                        --checklist \
                        --column '' \
                        --column Einstellung \
                        --column Name \
                        --height $WINETRICKS_MENU_HEIGHT \
                        --width $WINETRICKS_MENU_WIDTH \
                        "
                    ;;
                pl*) printf %s "zenity \
                        --title '$_W_msg_title' \
                        --text '$_W_msg_body' \
                        --list \
                        --checklist \
                        --column '' \
                        --column Ustawienie \
                        --column Nazwa \
                        --height $WINETRICKS_MENU_HEIGHT \
                        --width $WINETRICKS_MENU_WIDTH \
                        "
                    ;;
                ru*) printf %s "zenity \
                        --title '$_W_msg_title' \
                        --text '$_W_msg_body' \
                        --list \
                        --checklist \
                        --column '' \
                        --column Установка \
                        --column Имя \
                        --height $WINETRICKS_MENU_HEIGHT \
                        --width $WINETRICKS_MENU_WIDTH \
                        "
                    ;;
                uk*) printf %s "zenity \
                        --title '$_W_msg_title' \
                        --text '$_W_msg_body' \
                        --list \
                        --checklist \
                        --column '' \
                        --column Установка \
                        --column Назва \
                        --height $WINETRICKS_MENU_HEIGHT \
                        --width $WINETRICKS_MENU_WIDTH \
                        "
                    ;;
                zh_CN*) printf %s "zenity \
                        --title '$_W_msg_title' \
                        --text '$_W_msg_body' \
                        --list \
                        --checklist \
                        --column '' \
                        --column 设置 \
                        --column 标题 \
                        --height $WINETRICKS_MENU_HEIGHT \
                        --width $WINETRICKS_MENU_WIDTH \
                        "
                    ;;
                zh_TW*|zh_HK*) printf %s "zenity \
                        --title '$_W_msg_title' \
                        --text '$_W_msg_body' \
                        --list \
                        --checklist \
                        --column '' \
                        --column 設定 \
                        --column 標題 \
                        --height $WINETRICKS_MENU_HEIGHT \
                        --width $WINETRICKS_MENU_WIDTH \
                        "
                    ;;
                *) printf %s "zenity \
                        --title '$_W_msg_title' \
                        --text '$_W_msg_body' \
                        --list \
                        --checklist \
                        --column '' \
                        --column Setting \
                        --column Title \
                        --height $WINETRICKS_MENU_HEIGHT \
                        --width $WINETRICKS_MENU_WIDTH \
                        "
                    ;;
            esac > "$WINETRICKS_WORKDIR"/zenity.sh

            for metadatafile in "$WINETRICKS_METADATA/$WINETRICKS_CURMENU"/*.vars; do
                code=$(winetricks_metadata_basename "$metadatafile")
                (
                    title='?'
                    # shellcheck disable=SC1090
                    . "$metadatafile"

                    # Begin 'title' strings localization code
                    # shellcheck disable=SC2154
                    case $LANG in
                    uk*)
                        case "$title_uk" in
                            "") ;;
                            *) title="$title_uk";;
                        esac
                    esac

                    # End of code
                    printf "%s %s %s %s" " " FALSE \
                            "$code" \
                            "\"$title\""
                )
            done >> "$WINETRICKS_WORKDIR"/zenity.sh

            sh "$WINETRICKS_WORKDIR"/zenity.sh | tr '|' ' '
            ;;

        kdialog)
            (
                printf %s "kdialog --geometry 600x400+100+100 --title '$_W_msg_title' --separate-output --checklist '$_W_msg_body' "
                winetricks_list_all | sed 's/\([^ ]*\)  *\(.*\)/\1 "\1 - \2" off /' | tr '\012' ' '
            ) > "$WINETRICKS_WORKDIR"/kdialog.sh

            sh "$WINETRICKS_WORKDIR"/kdialog.sh
            ;;
    esac

    unset _W_msg_body _W_msg_title
}

# Display the current menu, output list of verbs to execute to stdout
winetricks_showmenu()
{
    case $LANG in
        da*) _W_msg_title='Vælg en pakke'
             _W_msg_body='Vilken pakke vil du installere?'
             _W_cached="cached"
             ;;
        de*) _W_msg_title="Winetricks - Aktueller Prefix ist \"$WINEPREFIX\""
             _W_msg_body='Welche Paket(e) möchten Sie installieren?'
             _W_cached="gecached"
             ;;
        pl*) _W_msg_title="Winetricks - obecny prefiks to \"$WINEPREFIX\""
             _W_msg_body='Które paczki chesz zainstalować?'
             _W_cached="zarchiwizowane"
             ;;
        ru*) _W_msg_title="Winetricks - текущий путь wine (wineprefix) \"$WINEPREFIX\""
             _W_msg_body='Какое приложение(я) вы хотите установить?'
             _W_cached="в кэше"
             ;;
        uk*) _W_msg_title="Winetricks - поточний prefix \"$WINEPREFIX\""
             _W_msg_body='Які пакунки Ви хочете встановити?'
             _W_cached="кешовано"
             ;;
        zh_CN*)   _W_msg_title="Winetricks - 当前容器路径是 \"$WINEPREFIX\""
             _W_msg_body='您想要安装什么应用程序？'
             _W_cached="已缓存"
             ;;
        zh_TW*|zh_HK*)   _W_msg_title="Winetricks - 目前容器路徑是 \"$WINEPREFIX\""
             _W_msg_body='您想要安裝什麼應用程式？'
             _W_cached="已緩存"
             ;;
        *)   _W_msg_title="Winetricks - current prefix is \"$WINEPREFIX\""
             _W_msg_body='Which package(s) would you like to install?'
             _W_cached="cached"
             ;;
    esac


    case $WINETRICKS_GUI in
        zenity)
            case $LANG in
                da*) printf %s "zenity \
                        --title '$_W_msg_title' \
                        --text '$_W_msg_body' \
                        --list \
                        --checklist \
                        --column '' \
                        --column Pakke \
                        --column Navn \
                        --column Udgiver \
                        --column År \
                        --column Medie \
                        --column Status \
                        --height $WINETRICKS_MENU_HEIGHT \
                        --width $WINETRICKS_MENU_WIDTH \
                        "
                    ;;
                de*) printf %s "zenity \
                        --title '$_W_msg_title' \
                        --text '$_W_msg_body' \
                        --list \
                        --checklist \
                        --column '' \
                        --column Paket \
                        --column Name \
                        --column Herausgeber \
                        --column Jahr \
                        --column Media \
                        --column Status \
                        --height $WINETRICKS_MENU_HEIGHT \
                        --width $WINETRICKS_MENU_WIDTH \
                        "
                     ;;
                pl*) printf %s "zenity \
                        --title '$_W_msg_title' \
                        --text '$_W_msg_body' \
                        --list \
                        --checklist \
                        --column '' \
                        --column Pakiet \
                        --column Nazwa \
                        --column Wydawca \
                        --column Rok \
                        --column Media \
                        --column Status \
                        --height $WINETRICKS_MENU_HEIGHT \
                        --width $WINETRICKS_MENU_WIDTH \
                        "
                     ;;
                ru*) printf %s "zenity \
                        --title '$_W_msg_title' \
                        --text '$_W_msg_body' \
                        --list \
                        --checklist \
                        --column '' \
                        --column Пакет \
                        --column Название \
                        --column Издатель \
                        --column Год \
                        --column Источник \
                        --column Статус \
                        --height $WINETRICKS_MENU_HEIGHT \
                        --width $WINETRICKS_MENU_WIDTH \
                        "
                     ;;
                uk*) printf %s "zenity \
                        --title '$_W_msg_title' \
                        --text '$_W_msg_body' \
                        --list \
                        --checklist \
                        --column '' \
                        --column Пакунок \
                        --column Назва \
                        --column Видавець \
                        --column Рік \
                        --column Медіа \
                        --column Статус \
                        --height $WINETRICKS_MENU_HEIGHT \
                        --width $WINETRICKS_MENU_WIDTH \
                        "
                     ;;
                zh_CN*) printf %s "zenity \
                        --title '$_W_msg_title' \
                        --text '$_W_msg_body' \
                        --list \
                        --checklist \
                        --column '' \
                        --column 包名 \
                        --column 软件名 \
                        --column 发行商 \
                        --column 发行年 \
                        --column 媒介 \
                        --column 状态 \
                        --height $WINETRICKS_MENU_HEIGHT \
                        --width $WINETRICKS_MENU_WIDTH \
                        "
                     ;;
                zh_TW*|zh_HK*) printf %s "zenity \
                        --title '$_W_msg_title' \
                        --text '$_W_msg_body' \
                        --list \
                        --checklist \
                        --column '' \
                        --column 包名 \
                        --column 軟體名 \
                        --column 發行商 \
                        --column 發行年 \
                        --column 媒介 \
                        --column 狀態 \
                        --height $WINETRICKS_MENU_HEIGHT \
                        --width $WINETRICKS_MENU_WIDTH \
                        "
                     ;;
                *) printf %s "zenity \
                        --title '$_W_msg_title' \
                        --text '$_W_msg_body' \
                        --list \
                        --checklist \
                        --column '' \
                        --column Package \
                        --column Title \
                        --column Publisher \
                        --column Year \
                        --column Media \
                        --column Status \
                        --height $WINETRICKS_MENU_HEIGHT \
                        --width $WINETRICKS_MENU_WIDTH \
                        "
                     ;;
            esac > "$WINETRICKS_WORKDIR"/zenity.sh

            true > "$WINETRICKS_WORKDIR"/installed.txt

            for metadatafile in "$WINETRICKS_METADATA/$WINETRICKS_CURMENU"/*.vars; do
                code=$(winetricks_metadata_basename "$metadatafile")
                (
                    title='?'
                    # shellcheck disable=SC1090
                    . "$metadatafile"
                    # Compute cached and downloadable flags
                    flags=""
                    winetricks_is_cached "$code" && flags="$_W_cached"
                    installed=FALSE
                    if winetricks_is_installed "$code"; then
                        installed=TRUE
                        echo "$code" >> "$WINETRICKS_WORKDIR"/installed.txt
                    fi
                    printf %s " $installed \
                        $code \
                        \"$title\" \
                        \"$publisher\" \
                        \"$year\" \
                        \"$media\" \
                        \"$flags\" \
                    "
                )
            done >> "$WINETRICKS_WORKDIR"/zenity.sh

            # Filter out any verb that's already installed
            sh "$WINETRICKS_WORKDIR"/zenity.sh |
                tr '|' '\012' |
                grep -F -v -x -f "$WINETRICKS_WORKDIR"/installed.txt |
                tr '\012' ' '
            ;;

        kdialog)
            (
                printf %s "kdialog --geometry 600x400+100+100 --title '$_W_msg_title' --separate-output --checklist '$_W_msg_body' "
                winetricks_list_all | sed 's/\([^ ]*\)  *\(.*\)/\1 "\1 - \2" off /' | tr '\012' ' '
            ) > "$WINETRICKS_WORKDIR"/kdialog.sh

            sh "$WINETRICKS_WORKDIR"/kdialog.sh
            ;;
    esac

    unset _W_msg_body _W_msg_title
}

# Converts a metadata absolute path to its app code
winetricks_metadata_basename()
{
    # Classic, but too slow on cygwin
    #basename $1 .vars

    # first, remove suffix .vars
    _W_mb_tmp="${1%.vars}"
    # second, remove any directory prefix
    echo "${_W_mb_tmp##*/}"
    unset _W_mb_tmp
}

# Returns true if given verb has been registered
winetricks_metadata_exists()
{
    test -f "$WINETRICKS_METADATA"/*/"${1}.vars"
}

# Returns true if given verb has been cached
# You must have already loaded its metadata before calling
winetricks_is_cached()
{
    # FIXME: also check file2... if given
    # https://github.com/Winetricks/winetricks/issues/989
    # shellcheck disable=SC2154
    _W_path="$W_CACHE/$1/$file1"
    case "$_W_path" in
        *..*)
            # Remove /foo/.. so verbs that don't have their own cache directories
            # can refer to siblings
            _W_path="$(echo "$_W_path" | sed 's,/[^/]*/\.\.,,')"
            ;;
    esac

    if test -f "$_W_path"; then
        unset _W_path
        return 0
    fi

    unset _W_path
    return 1
}

# Returns true if given verb has been installed
# You must have already loaded its metadata before calling
winetricks_is_installed()
{
    unset _W_file _W_file_unix
    if test "$installed_exe1"; then
        _W_file="$installed_exe1"
    elif test "$installed_file1"; then
        _W_file="$installed_file1"
    else
        return 1  # not installed
    fi

    # Test if the verb has been executed before
    if ! grep -qw "$1" "$WINEPREFIX/winetricks.log" 2>/dev/null; then
        unset _W_file
        return 1  # not installed
    fi

    case "$W_PLATFORM" in
        windows_cmd|wine_cmd)
            # On Windows, there's no wineprefix, just check if file's there
            _W_file_unix="$(w_pathconv -u "$_W_file")"
            if test -f "$_W_file_unix"; then
                unset _W_file _W_file_unix _W_prefix
                return 0  # installed
            fi
            ;;
        *)
            # Compute wineprefix for this app
            case "${_W_category}-${WINETRICKS_OPT_SHAREDPREFIX}" in
                apps-0|benchmarks-0|games-0)
                    _W_prefix="$W_PREFIXES_ROOT/$1"
                    ;;
                *)
                    _W_prefix="$WINEPREFIX"
                    ;;
            esac
            if test -d "$_W_prefix/dosdevices"; then
              # 'win7 vcrun2005' creates different file than 'winxp vcrun2005'
              # so let it specify multiple, separated by |
              _W_IFS="$IFS"
              IFS='|'
              for _W_file_ in $_W_file; do
                _W_file_unix="$(WINEPREFIX="$_W_prefix" w_pathconv -u "$_W_file_")"
                if test -f "$_W_file_unix" && ! grep -q "Wine placeholder DLL" "$_W_file_unix"; then
                    IFS="$_W_IFS"
                    unset _W_file _W_file_ _W_file_unix _W_prefix _W_IFS
                    return 0  # installed
                fi
              done
             IFS="$_W_IFS"
            fi
            ;;
    esac
    unset _W_file _W_prefix _W_IFS  # leak _W_file_unix for caller. Is this wise?
    return 1  # not installed
}

# List verbs which are already fully cached locally
winetricks_list_cached()
{
    for _W_metadatafile in "$WINETRICKS_METADATA"/*/*.vars; do
        # Use a subshell to avoid putting metadata in global space
        # If this is too slow, we can unset known metadata by hand
        (
        code=$(winetricks_metadata_basename "$_W_metadatafile")
        # shellcheck disable=SC1090
        . "$_W_metadatafile"
        if winetricks_is_cached "$code"; then
            echo "$code"
        fi
        )
    done | sort
    unset _W_metadatafile
}

# List verbs which are automatically downloadable, regardless of whether they're cached yet
winetricks_list_download()
{
    # Piping output of w_try_cd to /dev/null since winetricks-test parses it:
    w_try_cd "$WINETRICKS_METADATA" >/dev/null
    grep -l 'media=.download' ./*/*.vars | sed 's,.*/,,;s/\.vars//' | sort -u
}

# List verbs which are downloadable with user intervention, regardless of whether they're cached yet
winetricks_list_manual_download()
{
    # Piping output of w_try_cd to /dev/null since winetricks-test parses it:
    w_try_cd "$WINETRICKS_METADATA" >/dev/null
    grep -l 'media=.manual_download' ./*/*.vars | sed 's,.*/,,;s/\.vars//' | sort -u
}

winetricks_list_installed()
{
    # Rather than check individual metadata/files (which is slow/brittle, and also breaks settings and metaverbs)
    # just show winetricks.log (if it exists), which lists verbs in the order they were installed
    if [ -f "$WINEPREFIX/winetricks.log" ]; then
        cat "$WINEPREFIX/winetricks.log"
    else
        echo "warning: $WINEPREFIX/winetricks.log not found; winetricks has not installed anything in this prefix."
    fi
}

# Helper for adding a string to a list of flags
winetricks_append_to_flags()
{
    if test "$flags"; then
        flags="$flags,"
    fi
    flags="${flags}$1"
}

# List all verbs in category WINETRICKS_CURMENU verbosely
# Format is "verb  title  (publisher, year) [flags]"
winetricks_list_all()
{
    # Note: doh123 relies on 'winetricks list' to list main menu categories
    case $WINETRICKS_CURMENU in
        prefix|main|mkprefix) echo "$WINETRICKS_CATEGORIES" | sed 's/ mkprefix//' | tr ' ' '\012' ; return;;
    esac

    case $LANG in
        da*) _W_cached="cached"   ; _W_download="kan hentes"    ;;
        de*) _W_cached="gecached" ; _W_download="herunterladbar";;
        pl*) _W_cached="zarchiwizowane"   ; _W_download="do pobrania"  ;;
        ru*) _W_cached="в кэше"   ; _W_download="доступно для скачивания"  ;;
        uk*) _W_cached="кешовано"   ; _W_download="завантажуване"  ;;
        zh_CN*)   _W_cached="已缓存"   ; _W_download="可下载"  ;;
        zh_TW*|zh_HK*)   _W_cached="已緩存"   ; _W_download="可下載"  ;;
        *)   _W_cached="cached"   ; _W_download="downloadable"  ;;
    esac

    for _W_metadatafile in "$WINETRICKS_METADATA/$WINETRICKS_CURMENU"/*.vars; do
        # Use a subshell to avoid putting metadata in global space
        # If this is too slow, we can unset known metadata by hand
        (
        code=$(winetricks_metadata_basename "$_W_metadatafile")
        # shellcheck disable=SC1090
        . "$_W_metadatafile"

        # Compute cached and downloadable flags
        flags=""
        test "$media" = "download" && winetricks_append_to_flags "$_W_download"
        winetricks_is_cached "$code" && winetricks_append_to_flags "$_W_cached"
        test "$flags" && flags="[$flags]"

        if ! test "$year" && ! test "$publisher"; then
            printf "%-24s %s %s\\n" "$code" "$title" "$flags"
        else
            printf "%-24s %s (%s, %s) %s\\n" "$code" "$title" "$publisher" "$year" "$flags"
        fi
        )
    done
    unset _W_cached _W_metadatafile
}

# Abort if user doesn't own the given directory (or its parent, if it doesn't exist yet)
winetricks_die_if_user_not_dirowner()
{
    if test -d "$1"; then
        _W_checkdir="$1"
    else
        # fixme: quoting problem?
        _W_checkdir=$(dirname "$1")
    fi
    _W_nuser=$(id -u)
    _W_nowner=$(stat -c '%u' "$_W_checkdir")
    if test x"$_W_nuser" != x"$_W_nowner"; then
        w_die "You ($(id -un)) don't own $_W_checkdir.  Don't run this tool as another user!"
    fi
}

# See
# https://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf (iso9660)
# https://www.ecma-international.org/publications/files/ECMA-ST/Ecma-167.pdf
# http://www.osta.org/specs/pdf/udf102.pdf
# https://www.ecma-international.org/publications/techreports/E-TR-071.htm

# Usage: read_bytes offset count device
winetricks_read_bytes()
{
    dd status=noxfer if="$3" bs=1 skip="$1" count="$2" 2>/dev/null
}

# Usage: read_hex offset count device
winetricks_read_hex()
{
    od -j "$1" -N "$2" -t x1 "$3"     | # offset $1, count $2, single byte hex format, file $3
        sed 's/^[^ ]* //'             | # remove address
        sed '$d'                        # remove final line which is just final offset
}

# Usage: read_decimal offset device
# Reads single four byte word, outputs in decimal.
# Uses default endianness.
# udf uses little endian words, so this only works on little endian machines.
winetricks_read_decimal()
{
    od -j "$1" -N 4  -t u4 "$2"          | # offset $1, byte count 4, four byte decimal format, file $2
        sed 's/^[^ ]* //'             | # remove address
        sed '$d'                        # remove final line which is just final offset
}

winetricks_read_udf_volume_name()
{
    # "Anchor volume descriptor pointer" starts at sector 256

    # AVDP Layout (ECMA-167 3/10.2):
    # size   offset   contents
    # 16     0        descriptor tag (id = 2)
    # 16     8        main (primary?) volume descriptor sequence extent
    # ...

    # descriptor tag layout (ECMA-167 3/7.2):
    # size   offset   contents
    # 2      0        TagIdentifier
    # ...

    # extent layout (ECMA-167 3/7.1):
    # size   offset   contents
    # 4      0        length (in bytes)
    # 8      4        location (in 2k sectors)

    # primary volume descriptor layout (ECMA-167 3/10.1):
    # size   offset   contents
    # 16     0        descriptor tag (id = 1)
    # ...
    # 32     24       volume identifier (dstring)

    # 1. check the 16 bit TagIdentifier of the descriptor tag, make sure it's 2
    tagid=$(winetricks_read_hex 524288 2 "$1")
    : echo "tagid is $tagid"
    case "$tagid" in
        "02 00") : echo "Found AVDP" ;;
        *) echo "Did not find AVDP (tagid was $tagid)"; exit 1;;
    esac

    # 2. read the location of the main volume descriptor:
    offset=$(winetricks_read_decimal 524308 "$1")
    : echo "MVD is at sector $offset"
    offset=$((offset * 2048))
    : echo "MVD is at byte $offset"

    # 3. check the TagIdentifier of the MVD's descriptor tag, make sure it's 1
    tagid=$(winetricks_read_hex $offset 2 "$1")
    : echo "tagid is $tagid"
    case "$tagid" in
        "01 00") : echo Found MVD ;;
        *) echo Did not find MVD; exit 1;;
    esac

    # 4. Read whether the name is in 8 or 16 bit chars
    offset=$((offset + 24))
    width=$(winetricks_read_hex $offset 1 "$1")

    offset=$((offset + 1))

    # 5. Profit!
    case $width in
        08)   winetricks_read_bytes $offset 30 "$1" | sed 's/  *$//' ;;
        10)  winetricks_read_bytes $offset 30 "$1" | tr -d '\000' | sed 's/  *$//' ;;
        *) echo "Unhandled dvd volname character width '$width'"; exit 1;;
    esac

    echo ""
}

winetricks_read_iso9660_volume_name()
{
    winetricks_read_bytes 32808 30 "$1" | sed 's/  *$//'
}

winetricks_read_volume_name()
{
    # ECMA-119 says that CD-ROMs have sector size 2k, and at sector 16 have:
    # size  offset contents
    #  1    0      Volume descriptor type (1 for primary volume descriptor)
    #  5    1      Standard identifier ("CD001" for iso9660)
    # ECMA-167, section 9.1.2, has a table of standard identifiers:
    # "BEA01": ecma-167 9.2, Beginning Extended Area Descriptor
    # "CD001": ecma-119
    # "CDW02": ecma-168

    std_id=$(winetricks_read_bytes 32769 5 "$1")
    : echo "std_id is $std_id"

    case $std_id in
        CD001) winetricks_read_iso9660_volume_name "$1" ;;
        BEA01) winetricks_read_udf_volume_name "$1" ;;
        *) echo "Unrecognized disk type $std_id"; exit 1 ;;
    esac
}

winetricks_volname()
{
    x=$(volname "$1" 2> /dev/null| sed 's/  *$//')
    if test "x$x" = "x"; then
        # UDF?  See https://bugs.launchpad.net/bugs/678419
        x=$(winetricks_read_volume_name "$1")
    fi
    echo "$x"
}

# Really, should take a volume name as argument, and use 'mount' to get
# mount point if system automounted it.
winetricks_detect_optical_drive()
{
    case "$WINETRICKS_DEV" in
        "") ;;
        *) return ;;
    esac

    for WINETRICKS_DEV in /dev/cdrom /dev/dvd /dev/sr0; do
        test -b $WINETRICKS_DEV && break
    done

    case "$WINETRICKS_DEV" in
        "x") w_die "can't find cd/dvd drive" ;;
    esac
}

winetricks_cache_iso()
{
    # WINETRICKS_IMG has already been set by w_mount
    _W_expected_volname="$1"

    winetricks_die_if_user_not_dirowner "$W_CACHE"
    winetricks_detect_optical_drive

    # Horrible hack for Gentoo - make sure we can read from the drive
    if ! test -r $WINETRICKS_DEV; then
        case "$WINETRICKS_SUDO" in
            gksu*|kdesudo) $WINETRICKS_SUDO "chmod 666 $WINETRICKS_DEV" ;;
            kdesu) $WINETRICKS_SUDO -c "chmod 666 $WINETRICKS_DEV" ;;
            *) $WINETRICKS_SUDO chmod 666 $WINETRICKS_DEV ;;
        esac
    fi

    while true; do
        # Wait for user to insert disc.
        # Sleep long to make it less likely to close the drive during insertion.
        while ! dd if=$WINETRICKS_DEV of=/dev/null count=1; do
            sleep 5
        done

        # Some distributions automount discs in /media, take advantage of that
        if test -d "/media/_W_expected_volname"; then
            break
        fi
        # Otherwise try and read it straight from unmounted volume
        _W_volname=$(winetricks_volname $WINETRICKS_DEV)
        if test "$_W_expected_volname" != "$_W_volname"; then
            case $LANG in
                da*)  w_warn "Forkert disk [$_W_volname] indsat. Indsæt venligst disken [$_W_expected_volname]" ;;
                de*)  w_warn "Falsche Disk [$_W_volname] eingelegt. Bitte legen Sie Disk [$_W_expected_volname] ein!" ;;
                pl*)  w_warn "Umieszczono zły dysk [$_W_volname]. Proszę włożyć dysk [$_W_expected_volname]" ;;
                ru*)  w_warn "Неверный диск [$_W_volname]. Пожалуйста, вставьте диск [$_W_expected_volname]" ;;
                uk*)  w_warn "Неправильний диск [$_W_volname]. Будь ласка, вставте диск [$_W_expected_volname]" ;;
                zh_CN*)    w_warn " [$_W_volname] 光盘插入错误，请插入光盘 [$_W_expected_volname]" ;;
                zh_TW*|zh_HK*)    w_warn " [$_W_volname] 光碟插入錯誤，請插入光碟 [$_W_expected_volname]" ;;
                *)    w_warn "Wrong disc [$_W_volname] inserted.  Please insert disc [$_W_expected_volname]" ;;
            esac

            sleep 10
        else
            break
        fi
    done

    # Copy disc to .iso file, display progress every 5 seconds
    # Use conv=noerror,sync to replace unreadable blocks with zeroes
    case $WINETRICKS_OPT_DD in
        dd)
          $WINETRICKS_OPT_DD if=$WINETRICKS_DEV of="$W_CACHE"/temp.iso bs=2048 conv=noerror,sync &
          WINETRICKS_DD_PID=$!
          ;;
        ddrescue)
          if [ ! -x "$(command -v ddrescue)" ]; then
              w_die "Please install ddrescue first."
          fi
          $WINETRICKS_OPT_DD -v -b 2048 $WINETRICKS_DEV "$W_CACHE"/temp.iso &
          WINETRICKS_DD_PID=$!
          ;;
    esac

    echo "$WINETRICKS_DD_PID" > "$WINETRICKS_WORKDIR"/dd-pid

    # Note: if user presses ^C, winetricks_cleanup will call winetricks_iso_cleanup
    # FIXME: add progress bar for kde, too
    case $WINETRICKS_GUI in
        none|kdialog)
            while ps -p "$WINETRICKS_DD_PID" > /dev/null 2>&1; do
                sleep 5
                ls -l "$W_CACHE"/temp.iso
            done
            ;;
        zenity)
            while ps -p "$WINETRICKS_DD_PID" > /dev/null 2>&1; do
                echo 1
                sleep 2
            done | $WINETRICKS_GUI --title "Copying to $_W_expected_volname.iso" --progress --pulsate --auto-kill
            ;;
    esac
    rm "$WINETRICKS_WORKDIR"/dd-pid

    mv "$W_CACHE"/temp.iso "$WINETRICKS_IMG"

    eject $WINETRICKS_DEV || true    # punt if eject not found (as on cygwin)
}

winetricks_load_vcdmount()
{
    if test "$WINE" != ""; then
        return
    fi

    # Call only on real Windows.
    # Sets VCD_DIR and W_ISO_MOUNT_ROOT

    # The only free mount tool I know for Windows Vista is Virtual CloneDrive,
    # which can be downloaded at
    # http://www.slysoft.com/en/virtual-clonedrive.html
    # FIXME: actually install it here

    # Locate vcdmount.exe.
    VCD_DIR="Elaborate Bytes/VirtualCloneDrive"
    if test ! -x "$W_PROGRAMS_UNIX/$VCD_DIR/vcdmount.exe" && test ! -x "$W_PROGRAMS_X86_UNIX/$VCD_DIR/vcdmount.exe"; then
        w_warn "Installing Virtual CloneDrive"
        w_download_to vcd http://static.slysoft.com/SetupVirtualCloneDrive.exe
        # have to use cmd else vista won't let cygwin run .exe's?
        chmod +x "$W_CACHE"/vcd/SetupVirtualCloneDrive.exe
        w_try_cd "$W_CACHE/vcd"
        cmd /c SetupVirtualCloneDrive.exe
    fi
    if test -x "$W_PROGRAMS_UNIX/$VCD_DIR/vcdmount.exe"; then
        VCD_DIR="$W_PROGRAMS_UNIX/$VCD_DIR"
    elif test -x "$W_PROGRAMS_X86_UNIX/$VCD_DIR/vcdmount.exe"; then
        VCD_DIR="$W_PROGRAMS_X86_UNIX/$VCD_DIR"
    else
        w_die "can't find Virtual CloneDrive?"
    fi
    # FIXME: Use WMI to locate the drive named
    # "ELBY CLONEDRIVE..." using WMI as described in
    # https://delphihaven.wordpress.com/2009/07/05/using-wmi-to-get-a-drive-friendly-name/
}

winetricks_mount_cached_iso()
{
    # On entry, WINETRICKS_IMG is already set
    w_umount

    if test "$WINE" = ""; then
        winetricks_load_vcdmount
        my_img_win="$(w_pathconv -w "$WINETRICKS_IMG" | tr '\012' ' ' | sed 's/ $//')"
        w_try_cd "$VCD_DIR"
        w_try vcdmount.exe /l="$letter" "$my_img_win"

        tries=0
        while test $tries -lt 20; do
            for W_ISO_MOUNT_LETTER in e f g h i j k; do
                # let user blacklist drive letters
                echo "$WINETRICKS_MOUNT_LETTER_IGNORE" | grep -q "$W_ISO_MOUNT_LETTER" && continue
                W_ISO_MOUNT_ROOT=/cygdrive/$W_ISO_MOUNT_LETTER
                if find $W_ISO_MOUNT_ROOT -iname 'setup*' -o -iname '*.exe' -o -iname '*.msi'; then
                    break 2
                fi
            done
            tries=$((tries + 1))
            echo "Waiting for mount to finish mounting"
            sleep 1
        done
    else
        if test "$W_USE_USERMOUNT"; then
            # Linux (FUSE-based tools), macOS (hdiutil)
            if test "$WINETRICKS_ISO_MOUNT" = "none"; then
                # If no tools found, fall back to sudo + mount
                w_warn "No user mount tools detected, using sudo + mount"
                unset W_USE_USERMOUNT
                winetricks_mount_cached_iso
                return
            fi
            echo "Running mkdir -p $W_ISO_USER_MOUNT_ROOT"
            mkdir -p "$W_ISO_USER_MOUNT_ROOT"
            if test $? -ne 0; then
                w_warn "mkdir -p $W_ISO_USER_MOUNT_ROOT failed, falling back to sudo + mount"
                unset W_USE_USERMOUNT
                winetricks_mount_cached_iso
                return
            fi
            case "$WINETRICKS_ISO_MOUNT" in
                fuseiso)
                    echo "Running $WINETRICKS_ISO_MOUNT $WINETRICKS_IMG $W_ISO_USER_MOUNT_ROOT"
                    $WINETRICKS_ISO_MOUNT "$WINETRICKS_IMG" "$W_ISO_USER_MOUNT_ROOT"
                    ;;
                archivemount)
                    echo "Running $WINETRICKS_ISO_MOUNT $WINETRICKS_IMG $W_ISO_USER_MOUNT_ROOT -o readonly"
                    $WINETRICKS_ISO_MOUNT "$WINETRICKS_IMG" "$W_ISO_USER_MOUNT_ROOT" -o readonly
                    ;;
                hdiutil)
                    echo "Running $WINETRICKS_ISO_MOUNT attach -mountpoint $W_ISO_USER_MOUNT_ROOT $WINETRICKS_IMG"
                    $WINETRICKS_ISO_MOUNT attach -mountpoint "$W_ISO_USER_MOUNT_ROOT" "$WINETRICKS_IMG"
                    ;;
                *)
                    w_warn "Unknown ISO mount tool $WINETRICKS_ISO_MOUNT, using sudo + mount"
                    unset W_USE_USERMOUNT
                    winetricks_mount_cached_iso
                    return
                    ;;
            esac
            if test $? -ne 0; then
                w_warn "$WINETRICKS_ISO_MOUNT failed, falling back to sudo + mount"
                unset W_USE_USERMOUNT
                winetricks_mount_cached_iso
                return
            fi

            echo "Mounting as drive ${W_ISO_MOUNT_LETTER}:"
            # Gotta provide a symlink to the raw disc, else installers that check volume names will fail
            rm -f "$WINEPREFIX/dosdevices/${W_ISO_MOUNT_LETTER}:"*
            ln -sf "$WINETRICKS_IMG" "$WINEPREFIX/dosdevices/${W_ISO_MOUNT_LETTER}::"
            ln -sf "$W_ISO_USER_MOUNT_ROOT" "$WINEPREFIX/dosdevices/${W_ISO_MOUNT_LETTER}:"
            # Gotta set the type to "cdrom", else "wine eject" will fail
            cat > "$W_TMP"/set_type_cdrom.reg <<_EOF_
REGEDIT4

[HKEY_LOCAL_MACHINE\\Software\\Wine\\Drives]
"${W_ISO_MOUNT_LETTER}:"="cdrom"
_EOF_
            w_try_regedit "$W_TMP"/set_type_cdrom.reg
            # The new drive is not recognized without waiting
            # FIXME: not sure if the duration is appropriate
            sleep 5

            W_ISO_MOUNT_ROOT="$W_ISO_USER_MOUNT_ROOT"
        else
            # Linux (sudo + mount)
            _W_USERID=$(id -u)
            # WINETRICKS_IMG may contain spaces and needs to be quoted
            case "$WINETRICKS_SUDO" in
                gksu*|kdesudo)
                    w_try $WINETRICKS_SUDO "mkdir -p $W_ISO_MOUNT_ROOT"
                    w_try $WINETRICKS_SUDO "mount -o ro,loop,uid=$_W_USERID,unhide '$WINETRICKS_IMG' $W_ISO_MOUNT_ROOT"
                    ;;
                kdesu)
                    w_try $WINETRICKS_SUDO -c "mkdir -p $W_ISO_MOUNT_ROOT"
                    w_try $WINETRICKS_SUDO -c "mount -o ro,loop,uid=$_W_USERID,unhide '$WINETRICKS_IMG' $W_ISO_MOUNT_ROOT"
                    ;;
                *)
                    w_try $WINETRICKS_SUDO mkdir -p "$W_ISO_MOUNT_ROOT"
                    w_try $WINETRICKS_SUDO mount -o ro,loop,uid="$_W_USERID",unhide "$WINETRICKS_IMG" "$W_ISO_MOUNT_ROOT"
                    ;;
            esac

            echo "Mounting as drive ${W_ISO_MOUNT_LETTER}:"
            # Gotta provide a symlink to the raw disc, else installers that check volume names will fail
            rm -f "$WINEPREFIX/dosdevices/${W_ISO_MOUNT_LETTER}:"*
            ln -sf "$WINETRICKS_IMG" "$WINEPREFIX/dosdevices/${W_ISO_MOUNT_LETTER}::"
            ln -sf "$W_ISO_MOUNT_ROOT" "$WINEPREFIX/dosdevices/${W_ISO_MOUNT_LETTER}:"
            unset _W_USERID
        fi
    fi
}

# List the currently mounted UDF or iso9660 filesystems that match the given pattern
# Output format:
#   dev mountpoint
#   dev mountpoint
#   ...
# Mount points may contain spaces.

winetricks_list_mounts()
{
    mount | grep -E 'udf|iso9660' | sed 's,^\([^ ]*\) on \(.*\) type .*,\1 \2,'| grep "$1\$"
}

# Return success and set _W_dev _W_mountpoint if volume $1 is mounted
# Note: setting variables as a way of returning results from a
# shell function exposed several bugs in most shells (except ksh!)
# related to implicit subshells.  It would be better to output
# one string to stdout instead.
winetricks_is_mounted()
{
    # First, check for matching mountpoint
    _W_tmp="$(winetricks_list_mounts "$1")"
    if test "$_W_tmp"; then
        _W_dev=$(echo "$_W_tmp" | sed 's/ .*//')
        _W_mountpoint="$(echo "$_W_tmp" | sed 's/^[^ ]* //')"
        # Volume found!
        return 0
    fi

    # If that fails, read volume name the hard way for each volume
    # Have to use file to return results from implicit subshell
    rm -f "$W_TMP_EARLY/_W_tmp.$LOGNAME"
    winetricks_list_mounts . | while true; do
        IFS= read -r _W_tmp

        _W_dev=$(echo "$_W_tmp" | sed 's/ .*//')
        test "$_W_dev" || break
        _W_mountpoint="$(echo "$_W_tmp" | sed 's/^[^ ]* //')"
        _W_volname=$(winetricks_volname "$_W_dev")
        if test "$1" = "$_W_volname"; then
            # Volume found!  Want to return from function here, but can't
            echo "$_W_tmp" > "$W_TMP_EARLY/_W_tmp.$LOGNAME"
            break
        fi
    done

    if test -f "$W_TMP_EARLY/_W_tmp.$LOGNAME"; then
        # Volume found!  Return from function.
        _W_dev=$(sed 's/ .*//' "$W_TMP_EARLY/_W_tmp.$LOGNAME")
        _W_mountpoint="$(sed 's/^[^ ]* //' "$W_TMP_EARLY/_W_tmp.$LOGNAME")"
        rm -f "$W_TMP_EARLY/_W_tmp.$LOGNAME"
        return 0
    fi

    # Volume not found
    unset _W_dev _W_mountpoint _W_volname
    return 1
}

winetricks_mount_real_volume()
{
    _W_expected_volname="$1"

    # Wait for user to insert disc.

    case $LANG in
        da*)_W_mountmsg="Indsæt venligst disken '$_W_expected_volname' (krævet af pakken '$W_PACKAGE')" ;;
        de*)_W_mountmsg="Bitte Disk '$_W_expected_volname' einlegen (für Paket '$W_PACKAGE')" ;;
        pl*)  _W_mountmsg="Proszę włożyć dysk '$_W_expected_volname' (potrzebny paczce '$W_PACKAGE')" ;;
        ru*)  _W_mountmsg="Пожалуйста, вставьте том '$_W_expected_volname' (требуется для пакета '$W_PACKAGE')" ;;
        uk*)  _W_mountmsg="Будь ласка, вставте том '$_W_expected_volname' (потрібний для пакунка '$W_PACKAGE')" ;;
        zh_CN*)  _W_mountmsg="请插入卷 '$_W_expected_volname' (为包 '$W_PACKAGE 所需')" ;;
        zh_TW*|zh_HK*)  _W_mountmsg="請插入卷 '$_W_expected_volname' (為包 '$W_PACKAGE 所需')" ;;
        *)  _W_mountmsg="Please insert volume '$_W_expected_volname' (needed for package '$W_PACKAGE')" ;;
    esac

    if test "$WINE" = ""; then
        # Assume already mounted, just get drive letter
        W_ISO_MOUNT_LETTER=$(awk '/iso/ {print $1}' < /proc/mounts | tr -d :)
        W_ISO_MOUNT_ROOT=$(awk '/iso/ {print $2}' < /proc/mounts)
    else
        while ! winetricks_is_mounted "$_W_expected_volname"; do
            w_try w_warn_cancel "$_W_mountmsg"
            # In non-gui case, give user two seconds to futz with disc drive before spamming him again
            sleep 2
        done
        WINETRICKS_DEV=$_W_dev
        W_ISO_MOUNT_ROOT="$_W_mountpoint"

        # Gotta provide a symlink to the raw disc, else installers that check volume names will fail
        rm -f "$WINEPREFIX/dosdevices/${W_ISO_MOUNT_LETTER}:"*
        ln -sf "$WINETRICKS_DEV" "$WINEPREFIX/dosdevices/${W_ISO_MOUNT_LETTER}::"
        ln -sf "$W_ISO_MOUNT_ROOT" "$WINEPREFIX/dosdevices/${W_ISO_MOUNT_LETTER}:"
    fi

    # FIXME: need to remount some discs with unhide option,
    # add that as option to w_mount

    unset _W_mountmsg
}

winetricks_cleanup()
{
    # We don't want to run this multiple times, so unfortunately we have to run it here:
    if test "$W_NGEN_CMD"; then
        "$W_NGEN_CMD"
    fi

    set +e
    if test -f "$WINETRICKS_WORKDIR/dd-pid"; then
        # shellcheck disable=SC2046
        kill $(cat "$WINETRICKS_WORKDIR/dd-pid")
    fi
    test "$WINETRICKS_CACHE_SYMLINK" && rm -f "$WINETRICKS_CACHE_SYMLINK"
    test "$W_OPT_NOCLEAN" = 1 || rm -rf "$WINETRICKS_WORKDIR"
    # if $W_TMP_EARLY was created by mktemp, remove it (but not if W_OPT_NOCLEAN is set to 1):
    test "$W_OPT_NOCLEAN" = 1 || rm -rf "$W_TMP_EARLY"
    test "$W_OPT_NOCLEAN" = 1 || rm -rf "$WINEPREFIX"/wrapper.cfg
}

winetricks_set_unattended()
{
    # We shouldn't use all these extra variables.  Instead, we should
    # use ${foo:+bar} to jam in commandline options for silent install
    # only if W_OPT_UNATTENDED is nonempty.  See
    # https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02
    # So in attended mode, W_OPT_UNATTENDED should be empty.

    case "$1" in
        1)
            W_OPT_UNATTENDED=1
            # Might want to trim our stable of variables here a bit...
            W_UNATTENDED_SLASH_Q="/q"
            W_UNATTENDED_SLASH_QB="/qb"
            W_UNATTENDED_SLASH_QN="/qn"
            W_UNATTENDED_SLASH_QNT="/qnt"
            W_UNATTENDED_SLASH_QT="/qt"
            W_UNATTENDED_SLASH_QUIET="/quiet"
            W_UNATTENDED_SLASH_CAP_QUIET="/Quiet"
            W_UNATTENDED_SLASH_S="/S"
            W_UNATTENDED_DASH_SILENT="-silent"
            W_UNATTENDED_SLASH_SILENT="/silent"
            ;;
        *)
            W_OPT_UNATTENDED=""
            W_UNATTENDED_SLASH_Q=""
            W_UNATTENDED_SLASH_QB=""
            W_UNATTENDED_SLASH_QN=""
            W_UNATTENDED_SLASH_QNT=""
            W_UNATTENDED_SLASH_QT=""
            W_UNATTENDED_SLASH_QUIET=""
            W_UNATTENDED_SLASH_S=""
            W_UNATTENDED_DASH_SILENT=""
            W_UNATTENDED_SLASH_SILENT=""
            ;;
    esac
}

# Usage: winetricks_print_wineprefix_info
# Print some useful info about $WINEPREFIX if things fail in winetricks_set_wineprefix()
winetricks_print_wineprefix_info()
{
    printf "WINEPREFIX INFO:\\n"
    printf "Drive C: %s\\n\\n" "$(ls -al1 "${WINEPREFIX}/drive_c")"
    printf "Registry info:\\n"
    for regfile in "${WINEPREFIX}"/*.reg; do
        printf "%s:%s\\n" "${regfile}" "$(grep '#arch=' "${regfile}")"
    done
}

# Force creation of 32 or 64bit wineprefix on 64 bit systems.
# On 32bit systems, trying to create a 64bit wineprefix will fail.
# This must be called prior to winetricks_set_wineprefix()
winetricks_set_winearch()
{
    if [ "$1" = "32" ] || [ "$1" = "win32" ]; then
        export WINEARCH=win32
    elif [ "$1" = "64" ] || [ "$1" = "win64" ]; then
        export WINEARCH=win64
    else
        w_die "arch: Invalid architecture: $1"
    fi
}

# Usage: winetricks_set_wineprefix [bottlename]
# Bottlename must not contain spaces, slashes, or other special characters
# If bottlename is omitted, the default bottle (~/.wine) is used.
#
# shellcheck disable=SC2034
winetricks_set_wineprefix()
{
    # Note: these are arch independent, but are needed by some arch dependent variables
    # Defining here to avoid having two arch checks:
    if ! test "$1"; then
        WINEPREFIX="$WINETRICKS_ORIGINAL_WINEPREFIX"
    else
        WINEPREFIX="$W_PREFIXES_ROOT/$1"
    fi

    export WINEPREFIX
    w_try mkdir -p "$(dirname "$WINEPREFIX")"

    case "$W_PLATFORM" in
        windows_cmd)
            W_DRIVE_C="/cygdrive/c" ;;
        *)
            W_DRIVE_C="$WINEPREFIX/dosdevices/c:" ;;
    esac
    W_WINDIR_UNIX="$W_DRIVE_C/windows"

    # Make sure the prefix is initialized:
    w_try winetricks_early_wine cmd /c "echo init" > /dev/null 2>&1

    # Win(e) 32/64?
    # Using the variable W_SYSTEM32_DLLS instead of SYSTEM32 because some stuff does go under system32 for both arch's
    # e.g., spool/drivers/color
    if test -d "$W_DRIVE_C/windows/syswow64"; then
        # Probably need fancier handling/checking, but for a basic start:
        # Note 'wine' may be named 'wine-stable'/'wine-staging'/etc.):
        # WINE64 = wine64, available on 64-bit prefixes
        # WINE_ARCH = the native wine for the prefix (wine for 32-bit, wine64 for 64-bit)
        # WINE_MULTI = generic wine, new name
        if [ "${WINE%??}64" = "$WINE" ]; then
            WINE64="${WINE}"
        elif command -v "${WINE}64" >/dev/null 2>&1; then
            WINE64="${WINE}64"
        else
            # Handle case where wine binaries (or binary wrappers) have a suffix
            WINE64="$(dirname "$WINE")/"
            [ "$WINE64" = "./" ] && WINE64=""
            WINE64="${WINE64}$(basename "$WINE" | sed 's/^wine/wine64/')"
        fi
        WINE_ARCH="${WINE64}"
        WINE_MULTI="${WINE}"
        W_ARCH=win64

        W_PROGRAMS_WIN="$(w_expand_env ProgramFiles)"
        W_PROGRAMS_UNIX="$(w_pathconv -u "$W_PROGRAMS_WIN")"

        # Common variable for 32-bit dlls on win32/win64:
        W_32BIT_DLLS="$W_WINDIR_UNIX/syswow64"
        W_SYSTEM32_DLLS="$W_WINDIR_UNIX/syswow64"
        W_SYSTEM32_DLLS_WIN="C:\\windows\\syswow64"

        W_SYSTEM64_DLLS="$W_WINDIR_UNIX/system32"
        W_SYSTEM64_DLLS_WIN32="C:\\windows\\sysnative" # path to access 64-bit dlls from 32-bit apps
        W_SYSTEM64_DLLS_WIN64="C:\\windows\\system32"  # path to access 64-bit dlls from 64-bit apps

        # There's also ProgramW6432, which =%ProgramFiles%(but only available when running under a 64 bit OS)
        # See https://ss64.com/nt/syntax-variables.html
        W_PROGRAMW6432_WIN="$(w_expand_env ProgramW6432)"
        W_PROGRAMW6432_UNIX="$(w_pathconv -u "$W_PROGRAMW6432_WIN")"

        # 64-bit Windows has a second directory for program files
        W_PROGRAMS_X86_WIN="${W_PROGRAMS_WIN} (x86)"
        W_PROGRAMS_X86_UNIX="${W_PROGRAMS_UNIX} (x86)"

        W_COMMONFILES_X86_WIN="$(w_expand_env CommonProgramFiles\(x86\))"
        W_COMMONFILES_X86="$(w_pathconv -u "$W_COMMONFILES_X86_WIN")"
        W_COMMONFILES_WIN="$(w_expand_env CommonProgramW6432)"
        W_COMMONFILES="$(w_pathconv -u "$W_COMMONFILES_WIN")"

        # 64-bit prefixes still have plenty of issues:
        #case $LANG in
            #ru*) w_warn "Вы используете 64-битный WINEPREFIX. Важно: многие ветки устанавливают только 32-битные версии пакетов. Если у вас возникли проблемы, пожалуйста, проверьте еще раз на чистом 32-битном WINEPREFIX до отправки отчета об ошибке." ;;
            #*) w_warn "You are using a 64-bit WINEPREFIX. Note that many verbs only install 32-bit versions of packages. If you encounter problems, please retest in a clean 32-bit WINEPREFIX before reporting a bug." ;;
        #esac
    else
        WINE64="false"
        WINE_ARCH="${WINE}"
        WINE_MULTI="${WINE}"
        W_ARCH=win32

        W_PROGRAMS_WIN="$(w_expand_env ProgramFiles)"
        W_PROGRAMS_UNIX="$(w_pathconv -u "$W_PROGRAMS_WIN")"

        # Common variable for 32-bit dlls on win32/win64:
        W_32BIT_DLLS="$W_WINDIR_UNIX/system32"
        W_SYSTEM32_DLLS="$W_WINDIR_UNIX/system32"
        W_SYSTEM32_DLLS_WIN="C:\\windows\\system32"

        # These don't exist on win32, but are defined in case they are used on 32-bit.
        # W_SYSTEM64_DLLS_WIN64 in particular is needed by w_metadata()
        W_SYSTEM64_DLLS="/dev/null"
        W_SYSTEM64_DLLS_WIN32="C:\\does-not-exist-on-win32" # path to access 64-bit dlls from 32-bit apps
        W_SYSTEM64_DLLS_WIN64="C:\\does-not-exist-on-win32"  # path to access 64-bit dlls from 64-bit apps

        W_PROGRAMS_X86_WIN="${W_PROGRAMS_WIN}"
        W_PROGRAMS_X86_UNIX="${W_PROGRAMS_UNIX}"

        W_COMMONFILES_X86_WIN="$(w_expand_env CommonProgramFiles)"
        W_COMMONFILES_X86="$(w_pathconv -u "$W_COMMONFILES_X86_WIN")"
        W_COMMONFILES_WIN="$(w_expand_env CommonProgramFiles)"
        W_COMMONFILES="$(w_pathconv -u "$W_COMMONFILES_WIN")"
    fi

    ## Arch independent variables:

    # Note: using AppData since it's arch indepedent
    W_APPDATA_WIN="$(w_expand_env AppData)"
    W_APPDATA_UNIX="$(w_pathconv -u "$W_APPDATA_WIN")"

    case "$W_APPDATA_WIN" in
        "") w_info "$(winetricks_print_wineprefix_info)" ; w_die "$WINE cmd.exe /c echo '%AppData%' returned empty string, error message \"$(cat $W_TMP_EARLY/early_wine.err.txt)\" ";;
        %*) w_info "$(winetricks_print_wineprefix_info)" ; w_die "$WINE cmd.exe /c echo '%AppData%' returned unexpanded string '$W_PROGRAMS_WIN' ... this can be caused by a corrupt wineprefix (\`wineboot -u\` may help), by an old wine, or by not owning $WINEPREFIX" ;;
        *unknown*) w_info "$(winetricks_print_wineprefix_info)" ; w_die "$WINE cmd.exe /c echo '%AppData%' returned a string containing the word 'unknown', as if a voice had cried out in terror, and was suddenly silenced." ;;
    esac

    # Kludge: use Temp instead of temp to avoid \t expansion in w_try
    # but use temp in Unix path because that's what Wine creates, and having both temp and Temp
    # causes confusion (e.g. makes vc2005trial fail)
    if ! test "$1"; then
        W_TMP="$W_DRIVE_C/windows/temp"
        W_TMP_WIN="C:\\windows\\Temp"
    else
        # Verbs can rely on W_TMP being empty at entry, deleted after return, and a subdir of C:
        W_TMP="$W_DRIVE_C/windows/temp/_$1"
        W_TMP_WIN="C:\\windows\\Temp\\_$1"
    fi

    case "$W_PLATFORM" in
        "windows_cmd|wine_cmd") W_CACHE_WIN="$(w_pathconv -w "$W_CACHE")" ;;
        *)
            # For case where Z: doesn't exist or / is writable (!),
            # make a drive letter for W_CACHE. Clean it up on exit.
            test "$WINETRICKS_CACHE_SYMLINK" && rm -f "$WINETRICKS_CACHE_SYMLINK"
            for letter in y x w v u t s r q p o n m; do
                if ! test -d "$WINEPREFIX"/dosdevices/${letter}:; then
                    mkdir -p "$WINEPREFIX"/dosdevices
                    WINETRICKS_CACHE_SYMLINK="$WINEPREFIX"/dosdevices/${letter}:
                    ln -sf "$W_CACHE" "$WINETRICKS_CACHE_SYMLINK"
                    break
                fi
            done
            W_CACHE_WIN="${letter}:"
            ;;
    esac

    W_WINDIR_UNIX="$W_DRIVE_C/windows"

    # FIXME: get fonts path from SHGetFolderPath
    # See also https://blogs.msdn.microsoft.com/oldnewthing/20031103-00/?p=41973/
    W_FONTSDIR_WIN="c:\\windows\\Fonts"

    # FIXME: just convert path from Windows to Unix?
    # Did the user rename Fonts to fonts?
    if test ! -d "$W_WINDIR_UNIX"/Fonts && test -d "$W_WINDIR_UNIX"/fonts; then
        W_FONTSDIR_UNIX="$W_WINDIR_UNIX"/fonts
    else
        W_FONTSDIR_UNIX="$W_WINDIR_UNIX"/Fonts
    fi
    mkdir -p "${W_FONTSDIR_UNIX}"


    # Unset WINEARCH which might be set from winetricks_set_winearch().
    # It is no longer necessary after the new wineprefix was created
    # and even may cause trouble when using 64bit wineprefixes afterwards.
    unset WINEARCH
}

winetricks_annihilate_wineprefix()
{
    w_skip_windows "No wineprefix to delete on windows" && return

    case $LANG in
        uk*) w_askpermission "Бажаєте видалити '$WINEPREFIX'?" ;;
        pl*) w_askpermission "Czy na pewno chcesz usunąć prefiks $WINEPREFIX i wszystkie jego elementy?" ;;
        *) w_askpermission "Delete $WINEPREFIX, its apps, icons, and menu items?" ;;
    esac

    rm -rf "$WINEPREFIX"

    # Also remove menu items.
    find "$XDG_DATA_HOME/applications" -type f -name '*.desktop' -exec grep -q -l "$WINEPREFIX" '{}' ';' -exec rm '{}' ';'

    # Also remove desktop items.
    # Desktop might be synonym for home directory, so only go one level
    # deep to avoid extreme slowdown if user has lots of files
    (
    if ! test "$XDG_DESKTOP_DIR" && test -f "$XDG_CONFIG_HOME/user-dirs.dirs"; then
        # shellcheck disable=SC1090
        . "$XDG_CONFIG_HOME/user-dirs.dirs"
    fi
    find "$XDG_DESKTOP_DIR" -maxdepth 1 -type f -name '*.desktop' -exec grep -q -l "$WINEPREFIX" '{}' ';' -exec rm '{}' ';'
    )

    # FIXME: recover more nicely.  At moment, have to restart to avoid trouble.
    exit 0
}

winetricks_init()
{
    #---- Private Variables ----

    if ! test "$USERNAME"; then
        # Posix only requires LOGNAME to be defined, and sure enough, when
        # logging in via console and startx in Ubuntu 11.04, USERNAME isn't set!
        # And even normal logins in Ubuntu 13.04 doesn't set it.
        # I tried using only LOGNAME in this script, but it's so easy to slip
        # and use USERNAME, so define it here if needed.
        USERNAME="$LOGNAME"
    fi

    # Running Wine as root is (generally) bad, mmkay?
    if [ "$(id -u)" = 0 ]; then
        w_warn "Running Wine/winetricks as root is highly discouraged. See https://wiki.winehq.org/FAQ#Should_I_run_Wine_as_root.3F"
    fi

    # Ephemeral files for this run
    WINETRICKS_WORKDIR="$W_TMP_EARLY/w.$LOGNAME.$$"
    test "$W_OPT_NOCLEAN" = 1 || rm -rf "$WINETRICKS_WORKDIR"

    # Registering a verb creates a file in WINETRICKS_METADATA
    WINETRICKS_METADATA="$WINETRICKS_WORKDIR/metadata"

    # The list of categories is also hardcoded in winetricks_mainmenu() :-(
    WINETRICKS_CATEGORIES="apps benchmarks dlls fonts games settings mkprefix"
    for _W_cat in $WINETRICKS_CATEGORIES; do
        mkdir -p "$WINETRICKS_METADATA/$_W_cat"
    done

    # Which subdirectory of WINETRICKS_METADATA is currently active (or main, if none)
    WINETRICKS_CURMENU=prefix

    # Delete work directory after each run, on exit either graceful or abrupt
    trap winetricks_cleanup EXIT HUP INT QUIT ABRT

    # Whether to always cache cached iso's (1) or only use cache if present (0)
    # Can be inherited from environment or set via -k, defaults to off
    WINETRICKS_OPT_KEEPISOS=${WINETRICKS_OPT_KEEPISOS:-0}

    # what program to use to make disc image (dd or ddrescue)
    WINETRICKS_OPT_DD=${WINETRICKS_OPT_DD:-dd}

    # whether to use shared wineprefix (1) or unique wineprefix for each app (0)
    WINETRICKS_OPT_SHAREDPREFIX=${WINETRICKS_OPT_SHAREDPREFIX:-0}

    winetricks_get_sha256sum_prog

    winetricks_get_platform

    #---- Public Variables ----

    # Where application installers are cached
    # See https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
    # OSX: https://developer.apple.com/library/content/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/MacOSXDirectories/MacOSXDirectories.html

    if test -d "$HOME/Library"; then
        # OS X
        XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/Library/Caches}"
        XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/Library/Preferences}"
    else
        XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}"
        XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
    fi

    # shellcheck disable=SC2153
    if test "$WINETRICKS_DIR"; then
        # For backwards compatibility
        W_CACHE="${W_CACHE:-$WINETRICKS_DIR/cache}"
        WINETRICKS_POST="${WINETRICKS_POST:-$WINETRICKS_DIR/postinstall}"
    else
        W_CACHE="${W_CACHE:-$XDG_CACHE_HOME/winetricks}"
        WINETRICKS_POST="${WINETRICKS_POST:-$XDG_DATA_HOME/winetricks/postinstall}"
    fi

    WINETRICKS_AUTH="${WINETRICKS_AUTH:-$XDG_DATA_HOME/winetricks/auth}"

    # Config options are currently opt-in and not required, so not creating the config
    # directory unless there's demand:
    WINETRICKS_CONFIG="${XDG_CONFIG_HOME}/winetricks"
    #test -d "$WINETRICKS_CONFIG" || mkdir -p "$WINETRICKS_CONFIG"

    # Load country code from config file only when "--country=" option is not specified
    if test -z "$W_COUNTRY" -a -f "${WINETRICKS_CONFIG}"/country; then
        W_COUNTRY="$(cat "${WINETRICKS_CONFIG}"/country)"
    fi

    # Pin a task to a single cpu. Helps prevent race conditions.
    #
    # Linux/FreeBSD: supported
    # OSX: doesn't have a utility for this
    # Solaris: no access, PR welcome

    if [ -x "$(command -v taskset 2>/dev/null)" ]; then
        W_TASKSET="taskset -c 0"
    elif [ -x "$(command -v cpuset 2>/dev/null)" ]; then
        W_TASKSET="cpuset -l 0"
    else
        # not using w_warn so we don't annoy everyone running via GUI, but still printed to terminal:
        echo "warning: taskset/cpuset not available on your platform!"
        W_TASKSET=""
    fi

    # Whether to automate installs (0=no, 1=yes)
    winetricks_set_unattended ${W_OPT_UNATTENDED:-1}

    # We have to call this here, because it needs to be called before w_metadata
    # Unfortunately, that means we run wine before the gui runs. Avoiding that would take quite the refactor..
    winetricks_wine_setup "$@"
}

winetricks_wine_setup()
{
    # This used to be part of winetricks_init(), factored out because not everything needs Wine.
    if [ -n "$_W_wine_not_needed" ]; then
        # no-op
        :
        return
    fi

    # Overridden for windows
    W_ISO_MOUNT_ROOT=/mnt/winetricks
    W_ISO_USER_MOUNT_ROOT="$HOME"/winetricks-iso
    W_ISO_MOUNT_LETTER=i

    ######################
    # System-specific variables
    case "$W_PLATFORM" in
        windows_cmd)
            WINE=""
            WINE64=""
            WINE_ARCH=""
            WINE_MULTI=""
            WINESERVER=""
            W_DRIVE_C="C:/"
            ;;
        *)
            WINE="${WINE:-wine}"
            # Find wineserver.
            # Some distributions (Debian before wine 1.8-2) don't have it on the path.
            for x in \
                "$WINESERVER" \
                "${WINE}server" \
                "$(command -v wineserver 2> /dev/null)" \
                "$(dirname $WINE)/server/wineserver" \
                /usr/bin/wineserver-development \
                /usr/lib/wine/wineserver \
                /usr/lib/i386-kfreebsd-gnu/wine/wineserver \
                /usr/lib/i386-linux-gnu/wine/wineserver \
                /usr/lib/powerpc-linux-gnu/wine/wineserver \
                /usr/lib/i386-kfreebsd-gnu/wine/bin/wineserver \
                /usr/lib/i386-linux-gnu/wine/bin/wineserver \
                /usr/lib/powerpc-linux-gnu/wine/bin/wineserver \
                /usr/lib/x86_64-linux-gnu/wine/bin/wineserver \
                /usr/lib/i386-kfreebsd-gnu/wine-development/wineserver \
                /usr/lib/i386-linux-gnu/wine-development/wineserver \
                /usr/lib/powerpc-linux-gnu/wine-development/wineserver \
                /usr/lib/x86_64-linux-gnu/wine-development/wineserver \
                file-not-found; do

                if test -x "$x"; then
                    case "$x" in
                        /usr/lib/*/wine-development/wineserver|/usr/bin/wineserver-development)
                            if test -x /usr/bin/wine-development; then
                                WINE="/usr/bin/wine-development"
                            fi
                            ;;
                    esac
                    break
                fi
            done

                case "$x" in
                    file-not-found) w_die "wineserver not found!" ;;
                    *) WINESERVER="$x" ;;
                esac

                if test "$WINEPREFIX"; then
                    WINETRICKS_ORIGINAL_WINEPREFIX="$WINEPREFIX"
                else
                    WINETRICKS_ORIGINAL_WINEPREFIX="$HOME/.wine"
                fi
                _abswine="$(command -v "$WINE" 2>/dev/null)"
                if ! test -x "$_abswine" || ! test -f "$_abswine"; then
                    w_die "WINE is $WINE, which is neither on the path nor an executable file"
                fi
                unset _abswine
                ;;
    esac

    WINETRICKS_WINE_VERSION=${WINETRICKS_WINE_VERSION:-$(winetricks_early_wine --version | sed 's/.*wine/wine/')}
    WINETRICKS_ORIG_WINE_VERSION="${WINETRICKS_WINE_VERSION}"

    # Need to account for lots of variations:
    # wine-1.9.22
    # wine-1.9.22 (Debian 1.9.22-1)
    # wine-1.9.22 (Staging)
    # wine-2.0 (Debian 2.0-1)
    # wine-2.0-rc1
    # wine-2.8
    _wine_version_stripped="$(echo "$WINETRICKS_WINE_VERSION" | cut -d ' ' -f1 | sed -e 's/wine-//' -e 's/-rc.*//')"

    # If WINE is < 4.0, warn user:
    # 4.0 doesn't do what I thought it would
    if w_wine_version_in 3.99, ; then
        w_warn "Your version of wine $_wine_version_stripped is no longer supported upstream. You should upgrade to 4.x"
    fi

    winetricks_set_wineprefix "$1"

    if [ -z "$WINETRICKS_SUPER_QUIET" ] ; then
        echo "Using winetricks $(winetricks_print_version) with ${WINETRICKS_ORIG_WINE_VERSION} and WINEARCH=${W_ARCH}"
    fi
}

winetricks_usage()
{
    case $LANG in
        da*)
            cat <<_EOF_
Brug: $0 [tilvalg] [verbum|sti-til-verbum] ...
Kører de angivne verber.  Hvert verbum installerer et program eller ændrer en indstilling.
Tilvalg:
-k|--keep_isos: lagr iso'er lokalt (muliggør senere installation uden disk)
-q|--unattended: stil ingen spørgsmål, installér bare automatisk
-r|--ddrescue: brug alternativ disk-tilgangsmetode (hjælper i tilfælde af en ridset disk)
-t|--torify: Run downloads under torify, if available
-v|--verbose: vis alle kommandoer som de bliver udført
-V|--version: vis programversionen og afslut
-h|--help: vis denne besked og afslut
Diverse verber:
list: vis en liste over alle verber
list-cached: vis en liste over verber for allerede-hentede installationsprogrammer
list-download: vis en liste over verber for programmer der kan hentes
list-manual-download: list applications which can be downloaded with some help from the user
list-installed: list already-installed applications
annihilate            Delete ALL DATA AND APPLICATIONS INSIDE THIS WINEPREFIX
_EOF_
            ;;
        de*)
            cat <<_EOF_
Benutzung: $0 [options] [Kommando|Verb|Pfad-zu-Verb] ...
Angegebene Verben ausführen.
Jedes Verb installiert eine Anwendung oder ändert eine Einstellung.

Optionen:
    --force           Nicht prüfen ob Pakete bereits installiert wurden
    --gui             GUI Diagnosen anzeigen, auch wenn von der Kommandozeile gestartet
    --isolate         Jedes Programm oder Spiel in eigener Bottle (WINEPREFIX) installieren
-k, --keep_isos       ISOs local speichern (erlaubt spätere Installation ohne Disk)
    --no-clean        Temp Verzeichnisse nicht löschen (nützlich beim debuggen)
-q, --unattended      Keine Fragen stellen, alles automatisch installieren
-r, --ddrescue        Alternativer Zugriffsmodus (hilft bei zerkratzten Disks)
-t  --torify          Run downloads under torify, if available
    --verify          Wenn Möglisch automatische GUI Tests für Verben starten
-v, --verbose         Alle ausgeführten Kommandos anzeigen
-h, --help            Diese Hilfemeldung anzeigen
-V, --version         Programmversion anzeigen und Beenden

Kommandos:
list                  Kategorien auflisten
list-all              Alle Kategorien und deren Verben auflisten
dlls list             Verben der Kategorie 'DLLs' auflisten
settings list         Verben der Kategorie 'Einstellungen' auflisten
list-cached           Verben für bereits gecachte Installers auflisten
list-download         Verben für automatisch herunterladbare Anwendungen auflisten
list-manual-download  Verben für vom Benutzer herunterladbare Anwendungen auflisten
list-installed        Bereits installierte Verben auflisten
arch=32|64            Neues wineprefix mit 32 oder 64 bit erstellen, diese Option
                      muss vor prefix=foobar angegeben werden und funktioniert
                      nicht im Falle des Standard Wineprefix.
prefix=foobar         WINEPREFIX=$W_PREFIXES_ROOT/foobar auswählen
annihilate            ALLE DATEIEN UND PROGRAMME IN DIESEM WINEPREFIX Löschen
_EOF_
            ;;
        *)
            cat <<_EOF_
Usage: $0 [options] [command|verb|path-to-verb] ...
Executes given verbs.  Each verb installs an application or changes a setting.

Options:
    --country=CC      Set country code to CC and don't detect your IP address
-f,  --force           Don't check whether packages were already installed
    --gui             Show gui diagnostics even when driven by commandline
    --isolate         Install each app or game in its own bottle (WINEPREFIX)
    --self-update     Update this application to the last version
    --update-rollback Rollback the last self update
-k, --keep_isos       Cache isos (allows later installation without disc)
    --no-clean        Don't delete temp directories (useful during debugging)
-q, --unattended      Don't ask any questions, just install automatically
-r, --ddrescue        Retry hard when caching scratched discs
-t  --torify          Run downloads under torify, if available
    --verify          Run (automated) GUI tests for verbs, if available
-v, --verbose         Echo all commands as they are executed
-h, --help            Display this message and exit
-V, --version         Display version and exit

Commands:
list                  list categories
list-all              list all categories and their verbs
dlls list             list verbs in category 'dlls'
settings list         list verbs in category 'settings'
list-cached           list cached-and-ready-to-install verbs
list-download         list verbs which download automatically
list-manual-download  list verbs which download with some help from the user
list-installed        list already-installed verbs
arch=32|64            create wineprefix with 32 or 64 bit, this option must be
                      given before prefix=foobar and will not work in case of
                      the default wineprefix.
prefix=foobar         select WINEPREFIX=$W_PREFIXES_ROOT/foobar
annihilate            Delete ALL DATA AND APPLICATIONS INSIDE THIS WINEPREFIX
_EOF_
            ;;
    esac
}

#设置最后W_DOWNLOADURLS参数为url
W_DOWNLOADURLS="https://fancy-brook-66ae.vek.workers.dev"
#------------------------------------------------------------
winetricks_handle_option()
{
    case "$1" in
        --country=*) W_COUNTRY="${1##--country=}" ;;
        -f|--force) WINETRICKS_FORCE=1;;
        --gui) winetricks_detect_gui;;
        --Durl=*) W_DOWNLOADURLS="${!##--Durl=}" ;;
        -h|--help) winetricks_usage ; exit 0 ;;
        --isolate) WINETRICKS_OPT_SHAREDPREFIX=0 ;;
        -k|--keep_isos) WINETRICKS_OPT_KEEPISOS=1 ;;
        --no-clean) W_OPT_NOCLEAN=1 ;;
        --no-isolate) WINETRICKS_OPT_SHAREDPREFIX=1 ;;
        --optin) WINETRICKS_STATS_REPORT=1;;
        --optout) WINETRICKS_STATS_REPORT=0;;
        -q|--unattended) winetricks_set_unattended 1 ;;
        -r|--ddrescue) WINETRICKS_OPT_DD=ddrescue ;;
        --self-update) winetricks_selfupdate;;
        -t|--torify)  WINETRICKS_OPT_TORIFY=1 ;;
        --update-rollback) winetricks_selfupdate_rollback;;
        -v|--verbose) WINETRICKS_OPT_VERBOSE=1 ; set -x;;
        -V|--version) winetricks_print_version ; exit 0;;
        --verify) WINETRICKS_VERIFY=1 ;;
        -vv|--really-verbose) WINETRICKS_OPT_VERBOSE=2 ; set -x ;;
        -*) w_die "unknown option $1" ;;
        prefix=*) export WINEPREFIX="${W_PREFIXES_ROOT}/${1##prefix=}" ;;
        *) return 1 ;;
    esac
    return 0
}

# Test whether temporary directory is valid - before initialising script
[ -d "$W_TMP_EARLY" ] || w_die "temporary directory: '$W_TMP_EARLY' ; does not exist"
[ -w "$W_TMP_EARLY" ] || w_die "temporary directory: '$W_TMP_EARLY' ; is not user writeable"

# Must initialize variables before calling w_metadata
if ! test "$WINETRICKS_LIB"; then
    WINETRICKS_SRCDIR=$(dirname "$0")
    WINETRICKS_SRCDIR=$(w_try_cd "$WINETRICKS_SRCDIR"; pwd)

    # Which GUI helper to use (none/zenity/kdialog).  See winetricks_detect_gui.
    WINETRICKS_GUI=none
    # Default to a shared prefix:
    WINETRICKS_OPT_SHAREDPREFIX=${WINETRICKS_OPT_SHAREDPREFIX:-1}

    # Handle options before init, to avoid starting wine for --help or --version
    while winetricks_handle_option "$1"; do
        shift
    done

    # Super gross, but I couldn't find a cleaner way. This needs to be set for the list verbs (maybe others)
    # while also supporting `dlls list` (etc.)
    # This used by w_metadata() to skip checking installed files if wine isn't available/needed
    if echo "$*" | grep -v list-installed | grep -q -w list; then
        export _W_wine_not_needed=1
    fi

    # Workaround for https://github.com/Winetricks/winetricks/issues/599
    # If --isolate is used, pass verb to winetricks_init, so it can set the wineprefix using winetricks_set_wineprefix()
    # Otherwise, an arch mismatch between ${WINEPREFIX:-$HOME/.wine} and the prefix to be made for the isolated app would cause it to fail
    case $WINETRICKS_OPT_SHAREDPREFIX in
        0) winetricks_init "$1" ;;
        *) winetricks_init ;;
    esac
fi

winetricks_install_app()
{
    case $LANG in
        da*) fail_msg="Installationen af pakken $1 fejlede" ;;
        de*) fail_msg="Installieren von Paket $1 gescheitert" ;;
        pl*) fail_msg="Niepowodzenie przy instalacji paczki $1" ;;
        ru*) fail_msg="Ошибка установки пакета $1" ;;
        uk*) fail_msg="Помилка встановлення пакунка $1" ;;
        zh_CN*)   fail_msg="$1 安装失败" ;;
        zh_TW*|zh_HK*)   fail_msg="$1 安裝失敗" ;;
        *)   fail_msg="Failed to install package $1" ;;
    esac

    # FIXME: initialize a new wineprefix for this app, set lots of global variables
    if ! w_do_call "$1" "$2"; then
        w_die "$fail_msg"
    fi
}

winetricks_verify()
{
    "verify_$cmd" 2>/dev/null
    verify_status=$?
    case $verify_status in
        0) w_warn "verify_$cmd succeeded!" ;;
        127) echo "verify_$cmd not found, not verifying $cmd" ;;
        *) w_die "verify_$cmd failed!" ;;
    esac
}

#---- Builtin Verbs ----

#----------------------------------------------------------------
# Runtimes
#----------------------------------------------------------------

#----- common download for several verbs
# Note: please put a file list $(cabextract -l $foo) / $(unzip -l $foo) at ./misc/filelists/${helper}.txt

# Filelist at ./misc/filelists/directx-feb2010.txt
helper_directx_dl()
{
    # February 2010 DirectX 9c User Redistributable
    # https://www.microsoft.com/en-us/download/details.aspx?id=9033
    # FIXME: none of the verbs that use this will show download status right
    # until file1 metadata is extended to handle common cache dir
    w_download_to directx9 ${W_DOWNLOADURLS}/directx_feb2010_redist.exe f6d191e89a963d7cca34f169d30f49eab99c1ed3bb92da73ec43617caaa1e93f

    DIRECTX_NAME=directx_feb2010_redist.exe
}

# Filelist at ./misc/filelists/directx-jun2010.txt
helper_directx_Jun2010()
{
    # June 2010 DirectX 9c User Redistributable
    # https://www.microsoft.com/en-us/download/details.aspx?id=8109
    w_download_to directx9 ${W_DOWNLOADURLS}/directx_Jun2010_redist.exe

    DIRECTX_NAME=directx_Jun2010_redist.exe
}

# Filelist at ./misc/filelists/directx-jun2010.txt
helper_d3dx9_xx()
{
    dllname=d3dx9_$1

    helper_directx_Jun2010

    # Even kinder, less invasive directx - only extract and override d3dx9_xx.dll
    w_try_cabextract -d "$W_TMP" -L -F "*$dllname*x86*" "$W_CACHE"/directx9/$DIRECTX_NAME

    for x in "$W_TMP"/*.cab; do
      w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F "$dllname.dll" "$x"
    done

    if test "$W_ARCH" = "win64"; then
        w_try_cabextract -d "$W_TMP" -L -F "*$dllname*x64*" "$W_CACHE"/directx9/$DIRECTX_NAME

        for x in "$W_TMP"/*x64.cab; do
            w_try_cabextract -d "$W_SYSTEM64_DLLS" -L -F "$dllname.dll" "$x"
        done
    fi

    w_override_dlls native "$dllname"
}

# Filelist at ./misc/filelists/vb6sp6.txt
helper_vb6sp6()
{
    # $1 - directory to extract to
    # $2 .. $n - files to extract from the archive

    destdir="$1"
    shift

    w_download_to vb6sp6 ${W_DOWNLOADURLS}/VB60SP6-KB2708437-x86-ENU.msi 350602b2e084b39c97d1394c8594b18e41ef622315d4a9635c5e8ea6aa977b5e
    w_try_7z "$destdir" "$W_CACHE"/vb6sp6/VB60SP6-KB2708437-x86-ENU.msi "$@"
}

# Filelist at ./misc/filelists/win2ksp4.txt
helper_win2ksp4()
{
    filename=$1

    # Originally at https://www.microsoft.com/en-us/download/details.aspx?id=4127
    # Mirror list at http://www.filewatcher.com/m/w2ksp4_en.exe.135477136-0.html
    # This URL doesn't need rename from w2ksp4_en.exe to W2KSP4_EN.EXE
    # to avoid users having to redownload for a file rename
    w_download_to win2ksp4 ${W_DOWNLOADURLS}/W2KSP4_EN.EXE 167bb78d4adc957cc39fb4902517e1f32b1e62092353be5f8fb9ee647642de7e
    w_try_cabextract -d "$W_TMP" -L -F "$filename" "$W_CACHE"/win2ksp4/W2KSP4_EN.EXE
}

# Filelist at ./misc/filelists/winxpsp2_support_tools.txt
helper_winxpsp2_support_tools()
{
    filename="$1"

    # https://www.microsoft.com/en-us/download/details.aspx?id=18546
    w_download_to winxpsp2_support_tools ${W_DOWNLOADURLS}/WindowsXP-KB838079-SupportTools-ENU.exe 7927e87af616d2fb8d4ead0db0103eb845a4e6651b20a5bffea9eebc3035c24d

    w_try_cabextract -d "$W_TMP" -L -F support.cab "$W_CACHE"/winxpsp2_support_tools/WindowsXP-KB838079-SupportTools-ENU.exe
    w_try_cabextract -d "$W_TMP" -L -F "$filename" "$W_TMP"/support.cab
}

# Filelist at ./misc/filelists/winxpsp3.txt
helper_winxpsp3()
{
    filename=$1

    # 2017/03/15: helper was renamed from winxpsp3 to winxpsp3, to match win2k/win7 service pack helpers
    # To minimize user impact, renaming directory automagically.
    # This could be removed after a transition period (1 year or so):
    if [ -d "$W_CACHE/xpsp3" ] ; then
        w_try mv "$W_CACHE/xpsp3" "$W_CACHE/winxpsp3"
    fi

    # Formerly at:
    # https://www.microsoft.com/en-us/download/details.aspx?id=24
    # https://download.microsoft.com/download/d/3/0/d30e32d8-418a-469d-b600-f32ce3edf42d/WindowsXP-KB936929-SP3-x86-ENU.exe
    # Mirror list: http://www.filewatcher.com/m/WindowsXP-KB936929-SP3-x86-ENU.exe.331805736-0.html
    # 2018/04/04: http://www.download.windowsupdate.com/msdownload/update/software/dflt/2008/04/windowsxp-kb936929-sp3-x86-enu_c81472f7eeea2eca421e116cd4c03e2300ebfde4.exe
    w_download_to winxpsp3 ${W_DOWNLOADURLS}/WindowsXP-KB936929-SP3-x86-ENU.exe 62e524a552db9f6fd22d469010ea4d7e28ee06fa615a1c34362129f808916654

    w_try_cabextract -d "$W_TMP" -L -F "$filename" "$W_CACHE"/winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe
}

# Filelist at ./misc/filelists/win7sp1.txt
helper_win7sp1()
{
    filename=$1

    # https://www.microsoft.com/en-us/download/details.aspx?id=5842
    w_download_to win7sp1 ${W_DOWNLOADURLS}/windows6.1-KB976932-X86.exe e5449839955a22fc4dd596291aff1433b998f9797e1c784232226aba1f8abd97

    w_try_cabextract -d "$W_TMP" -L -F "$filename" "$W_CACHE"/win7sp1/windows6.1-KB976932-X86.exe
}

# Filelist at ./misc/filelists/win7sp1_x64.txt
helper_win7sp1_x64()
{
    filename=$1

    # https://www.microsoft.com/en-us/download/details.aspx?id=5842
    w_download_to win7sp1 ${W_DOWNLOADURLS}/windows6.1-KB976932-X64.exe f4d1d418d91b1619688a482680ee032ffd2b65e420c6d2eaecf8aa3762aa64c8

    w_try_cabextract -d "$W_TMP" -L -F "$filename" "$W_CACHE"/win7sp1/windows6.1-KB976932-X64.exe
}

#######################
# dlls
#######################

#---------------------------------------------------------

w_metadata adobeair dlls \
    title="Adobe AIR" \
    publisher="Adobe" \
    year="2018" \
    media="download" \
    file1="AdobeAIRInstaller.exe" \
    installed_file1="$W_COMMONFILES_X86_WIN/Adobe AIR/Versions/1.0/Adobe AIR.dll" \
    homepage="https://www.adobe.com/products/air/"

load_adobeair()
{
    # 2017/03/14: 20.0.0.260 (strings 'Adobe AIR.dll' | grep 20\\. ) sha256sum 318770b9a18e59ca4a721a1f5c2b0235cffdbe77a043e99cb2af32074d61de45
    # 2018/01/30: 28.0.0.127 (strings 'Adobe AIR.dll' | grep 28\\. ) sha256sum 9076489e273652089a4a53a1d38c6631e8b7477e39426a843e0273f25bfb109f
    # 2018/03/16: 29.0.0.112 (strings 'Adobe AIR.dll' | grep -E "^29\..+\..+" ) sha256sum 5186b54682644a30f2be61c9b510de9a9a76e301bc1b42f0f1bc50bd809a3625
    # 2018/06/08: 30.0.0.107 (strings 'Adobe AIR.dll' | grep -E "^30\..+\..+" ) sha256sum bcc36174f6f70baba27e5ed1c0df67e55c306ac7bc86b1d280eff4db8c314985
    # 2018/09/12: 31.0.0.96 (strings 'Adobe AIR.dll' | grep -E "^31\..+\..+" ) sha256sum dc82421f135627802b21619bdb7e4b9b0ec16d351120485c575aa6c16cd2737e
    # 2018/12/22: 32.0.0.89 (strings 'Adobe AIR.dll' | grep -E "^32\..+\..+" ) sha256sum 24532d41ef2588c0daac4b6f8b7f863ee3c1a1b1e90b2d8d8b3eb4faa657e5e3
    # 2019/06/11: 32.0.0.125 (strings 'Adobe AIR.dll' | grep -E "^32\..+\..+" ) sha256sum 6718308e10a45176155d0ecc8458bd3606308925b91f26a7d08c148cf52c9db3
    w_download ${W_DOWNLOADURLS}/AdobeAIRInstaller.exe 6718308e10a45176155d0ecc8458bd3606308925b91f26a7d08c148cf52c9db3
    w_try_cd "$W_CACHE/$W_PACKAGE"

    # See https://bugs.winehq.org/show_bug.cgi?id=43506
    # and https://github.com/Winetricks/winetricks/issues/821
    if w_workaround_wine_bug 43506 "Forcing quiet install"; then
        w_try "$WINE" AdobeAIRInstaller.exe -silent
    else
        w_try "$WINE" AdobeAIRInstaller.exe $W_UNATTENDED_DASH_SILENT
    fi
}

#----------------------------------------------------------------

w_metadata amstream dlls \
    title="MS amstream.dll" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/amstream.dll"

load_amstream()
{
    helper_win7sp1 x86_microsoft-windows-directshow-other_31bf3856ad364e35_6.1.7601.17514_none_0f58f1e53efca91e/amstream.dll
    w_try cp "$W_TMP/x86_microsoft-windows-directshow-other_31bf3856ad364e35_6.1.7601.17514_none_0f58f1e53efca91e/amstream.dll" "$W_SYSTEM32_DLLS/amstream.dll"

    w_override_dlls native,builtin amstream

    w_try_regsvr amstream.dll

    if [ "$W_ARCH" = "win64" ]; then
        helper_win7sp1_x64 amd64_microsoft-windows-directshow-other_31bf3856ad364e35_6.1.7601.17514_none_6b778d68f75a1a54/amstream.dll
        w_try cp "$W_TMP/amd64_microsoft-windows-directshow-other_31bf3856ad364e35_6.1.7601.17514_none_6b778d68f75a1a54/amstream.dll" "$W_SYSTEM64_DLLS/amstream.dll"
        w_try_regsvr64 amstream.dll
    fi
}

#----------------------------------------------------------------

w_metadata art2kmin dlls \
    title="MS Access 2007 runtime" \
    publisher="Microsoft" \
    year="2007" \
    media="download" \
    file1="AccessRuntime.exe" \
    installed_file1="$W_COMMONFILES_X86_WIN/Microsoft Shared/OFFICE12/ACEES.DLL"

load_art2kmin()
{
    # See https://www.microsoft.com/en-us/download/details.aspx?id=4438
    # Originally at https://download.microsoft.com/download/D/2/A/D2A2FC8B-0447-491C-A5EF-E8AA3A74FB98/AccessRuntime.exe
    # 2019/11/22: moved to https://www.fmsinc.com/microsoftaccess/runtime/AccessRuntime2007.exe
    w_download ${W_DOWNLOADURLS}/AccessRuntime2007.exe a00a92fdc4ddc0dcf5d1964214a8d7e4c61bb036908a4b43b3700063eda9f4fb AccessRuntime.exe
    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try "$WINE" AccessRuntime.exe $W_UNATTENDED_SLASH_Q
}

#----------------------------------------------------------------

w_metadata atmlib dlls \
    title="Adobe Type Manager" \
    publisher="Adobe" \
    year="2009" \
    media="download" \
    file1="../win2ksp4/W2KSP4_EN.EXE" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/atmlib.dll"

load_atmlib()
{
    helper_win2ksp4 i386/atmlib.dl_
    w_try_cabextract --directory="$W_SYSTEM32_DLLS" "$W_TMP"/i386/atmlib.dl_
}

#----------------------------------------------------------------

w_metadata avifil32 dlls \
    title="MS avifil32" \
    publisher="Microsoft" \
    year="2004" \
    media="download" \
    file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/avifil32.dll"

load_avifil32()
{
    helper_winxpsp3 i386/avifil32.dl_
    w_try_cabextract --directory="$W_SYSTEM32_DLLS" "$W_TMP"/i386/avifil32.dl_

    w_override_dlls native avifil32
}

#----------------------------------------------------------------

w_metadata cabinet dlls \
    title="Microsoft cabinet.dll" \
    publisher="Microsoft" \
    year="2002" \
    media="download" \
    file1="MDAC_TYP.EXE" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/cabinet.dll"

load_cabinet()
{
    # https://www.microsoft.com/downloads/en/details.aspx?FamilyId=9AD000F2-CAE7-493D-B0F3-AE36C570ADE8&displaylang=en
    # Originally at: https://download.microsoft.com/download/3/b/f/3bf74b01-16ba-472d-9a8c-42b2b4fa0d76/mdac_typ.exe
    # Mirror list: http://www.filewatcher.com/m/MDAC_TYP.EXE.5389224-0.html (5.14 MB MDAC_TYP.EXE)
    # 2018/08/09: ftp.gunadarma.ac.id is dead, moved to archive.org
    w_download ${W_DOWNLOADURLS}/MDAC_TYP.EXE 36d2a3099e6286ae3fab181a502a95fbd825fa5ddb30bf09b345abc7f1f620b4

    w_try_cabextract --directory="${W_TMP}" "${W_CACHE}/${W_PACKAGE}/${file1}"
    w_try cp "${W_TMP}/cabinet.dll" "${W_SYSTEM32_DLLS}/cabinet.dll"

    w_override_dlls native,builtin cabinet
}

#----------------------------------------------------------------

w_metadata cmd dlls \
    title="MS cmd.exe" \
    publisher="Microsoft" \
    year="2004" \
    media="download" \
    file1="Q811493_W2K_SP4_X86_EN.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/cmd.exe"

load_cmd()
{
    # Originally at: https://download.microsoft.com/download/8/d/c/8dc79965-dfbc-4b25-9546-e23bc4b791c6/Q811493_W2K_SP4_X86_EN.exe
    # Mirror list: http://www.filewatcher.com/_/?q=Q811493_W2K_SP4_X86_EN.exe
    w_download ${W_DOWNLOADURLS}/Q811493_W2K_SP4_X86_EN.exe b5574b3516a724c2cba0d864162a3d1d684db1cf30de8db4b0e0ea6a1f6f1480
    w_try_cabextract --directory="$W_SYSTEM32_DLLS" "$W_CACHE/$W_PACKAGE/$file1" -F cmd.exe

    w_override_dlls native,builtin cmd.exe
}

#----------------------------------------------------------------

w_metadata cnc_ddraw dlls \
    title="Reimplentation of ddraw for CnC games" \
    homepage="${W_DOWNLOADURLS}/cnc-ddraw" \
    publisher="CnCNet" \
    year="2020" \
    media="download" \
    file1="cnc-ddraw.zip" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/Shaders/readme.txt"

load_cnc_ddraw()
{
    # Note: only works if ddraw.ini contains settings for the executable
    w_download ${W_DOWNLOADURLS}/cnc-ddraw.zip c1f85053223ab04a573cc482b43b93a58077e928a401f3364c9dc5542ad090ae
    w_try_unzip "$W_SYSTEM32_DLLS" "$W_CACHE/$W_PACKAGE/$file1"

    w_override_dlls native,builtin ddraw
}

#----------------------------------------------------------------

w_metadata comctl32 dlls \
    title="MS common controls 5.80" \
    publisher="Microsoft" \
    year="2001" \
    media="download" \
    file1="cc32inst.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/comctl32.dll"

load_comctl32()
{
    # Microsoft has removed. Mirrors can be found at http://www.filewatcher.com/m/CC32inst.exe.587496-0.html
    # 2011/01/17: https://www.microsoft.com/en-us/download/details.aspx?id=14672
    # 2012/08/11: w_download https://download.microsoft.com/download/platformsdk/redist/5.80.2614.3600/w9xnt4/en-us/cc32inst.exe d68c0cca721870aed39f5f2efd80dfb74f3db66d5f9a49e7578b18279edfa4a7
    # 2016/01/07: w_download ftp://ftp.ie.debian.org/disk1/download.sourceforge.net/pub/sourceforge/p/po/pocmin/Win%2095_98%20Controls/Win%2095_98%20Controls/CC32inst.exe
    # 2017/03/12: w_download https://downloads.sourceforge.net/project/pocmin/Win%2095_98%20Controls/Win%2095_98%20Controls/CC32inst.exe

    w_download ${W_DOWNLOADURLS}/CC32inst.exe d68c0cca721870aed39f5f2efd80dfb74f3db66d5f9a49e7578b18279edfa4a7

    w_try "$WINE" "$W_CACHE"/comctl32/cc32inst.exe "/T:$W_TMP_WIN" /c $W_UNATTENDED_SLASH_Q
    w_try_unzip "$W_TMP" "$W_TMP"/comctl32.exe
    w_try "$WINE" "$W_TMP"/x86/50ComUpd.Exe "/T:$W_TMP_WIN" /c $W_UNATTENDED_SLASH_Q
    w_try cp "$W_TMP"/comcnt.dll "$W_SYSTEM32_DLLS"/comctl32.dll

    w_override_dlls native,builtin comctl32

    # some builtin apps don't like native comctl32
    w_override_app_dlls winecfg.exe builtin comctl32
    w_override_app_dlls explorer.exe builtin comctl32
    w_override_app_dlls iexplore.exe builtin comctl32
}

#----------------------------------------------------------------

w_metadata comctl32ocx dlls \
    title="MS comctl32.ocx and mscomctl.ocx, comctl32 wrappers for VB6" \
    publisher="Microsoft" \
    year="2012" \
    media="download" \
    file1="../vb6sp6/VB60SP6-KB2708437-x86-ENU.msi" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/mscomctl.ocx"

load_comctl32ocx()
{
    helper_vb6sp6 "$W_SYSTEM32_DLLS" comctl32.ocx mscomctl.ocx mscomct2.ocx

    w_try_regsvr comctl32.ocx
    w_try_regsvr mscomctl.ocx
    w_try_regsvr mscomct2.ocx
}

#----------------------------------------------------------------

w_metadata comdlg32ocx dlls \
    title="Common Dialog ActiveX Control for VB6" \
    publisher="Microsoft" \
    year="2012" \
    media="download" \
    file1="../vb6sp6/VB60SP6-KB2708437-x86-ENU.msi" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/comdlg32.ocx"

load_comdlg32ocx()
{
    helper_vb6sp6 "$W_TMP" ComDlg32.ocx
    w_try mv "$W_TMP/ComDlg32.ocx" "$W_SYSTEM32_DLLS/comdlg32.ocx"
    w_try_regsvr comdlg32.ocx
}

#----------------------------------------------------------------

w_metadata crypt32 dlls \
    title="MS crypt32" \
    publisher="Microsoft" \
    year="2004" \
    media="download" \
    file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/crypt32.dll"

load_crypt32()
{
    w_call msasn1

    helper_winxpsp3 i386/crypt32.dl_
    w_try_cabextract --directory="$W_SYSTEM32_DLLS" "$W_TMP"/i386/crypt32.dl_

    w_override_dlls native crypt32
}

#----------------------------------------------------------------

w_metadata binkw32 dlls \
    title="RAD Game Tools binkw32.dll" \
    publisher="RAD Game Tools, Inc." \
    year="2020" \
    media="download" \
    file1="binkw32.zip" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/binkw32.dll"

load_binkw32()
{
    # Mirror: https://www.dlldump.com/download-dll-files_new.php/dllfiles/B/binkw32.dll/1.0q/download.html
    # sha256sum of the decompressed file: 1fd7ef7873c8a3be7e2f127b306d0d24d7d88e20cf9188894eff87b5af0d495f
    #
    # Zip sha256sum:
    # 2015/12/27: f018823193df21aca65ebef27b9c2a5f32ac299d91014f33c79198fe6f9890d5

    w_download ${W_DOWNLOADURLS}/binkw32.zip f018823193df21aca65ebef27b9c2a5f32ac299d91014f33c79198fe6f9890d5

    w_try_unzip "$W_TMP" "$W_CACHE"/binkw32/binkw32.zip
    w_try cp "$W_TMP"/binkw32.dll "$W_SYSTEM32_DLLS"/binkw32.dll

    w_override_dlls native binkw32
}

#----------------------------------------------------------------

w_metadata d3dcompiler_42 dlls \
    title="MS d3dcompiler_42.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dcompiler_42.dll"

load_d3dcompiler_42()
{
    dllname=d3dcompiler_42

    helper_directx_Jun2010

    w_try_cabextract -d "$W_TMP" -L -F "*$dllname*x86*" "$W_CACHE"/directx9/$DIRECTX_NAME
    for x in "$W_TMP"/*.cab; do
      w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F "$dllname.dll" "$x"
    done
    if test "$W_ARCH" = "win64"; then
        w_try_cabextract -d "$W_TMP" -L -F "*$dllname*x64*" "$W_CACHE"/directx9/$DIRECTX_NAME
        for x in "$W_TMP"/*x64.cab; do
            w_try_cabextract -d "$W_SYSTEM64_DLLS" -L -F "$dllname.dll" "$x"
        done
    fi

    w_override_dlls native $dllname
}

#----------------------------------------------------------------

w_metadata d3dcompiler_43 dlls \
    title="MS d3dcompiler_43.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dcompiler_43.dll"

load_d3dcompiler_43()
{
    if w_workaround_wine_bug 24013; then
        w_warn "Native d3dcompiler_43 may cause some d3d10 apps to crash, see https://bugs.winehq.org/show_bug.cgi?id=24013"
    fi

    dllname=d3dcompiler_43

    helper_directx_Jun2010

    w_try_cabextract -d "$W_TMP" -L -F "*$dllname*x86*" "$W_CACHE"/directx9/$DIRECTX_NAME
    for x in "$W_TMP"/*.cab; do
      w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F "$dllname.dll" "$x"
    done
    if test "$W_ARCH" = "win64"; then
        w_try_cabextract -d "$W_TMP" -L -F "*$dllname*x64*" "$W_CACHE"/directx9/$DIRECTX_NAME
        for x in "$W_TMP"/*x64.cab; do
            w_try_cabextract -d "$W_SYSTEM64_DLLS" -L -F "$dllname.dll" "$x"
        done
    fi

    w_override_dlls native $dllname
}

#----------------------------------------------------------------

w_metadata d3dcompiler_47 dlls \
    title="MS d3dcompiler_47.dll" \
    publisher="Microsoft" \
    year="FIXME" \
    media="download" \
    file1="FirefoxSetup62.0.3-win32.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dcompiler_47.dll"

load_d3dcompiler_47()
{
    # FIXME: would be awesome to find a small download that has both 32/64bit dlls, but this works for now:

    w_download ${W_DOWNLOADURLS}/Firefox%20Setup%2062.0.3.exe "d6edb4ff0a713f417ebd19baedfe07527c6e45e84a6c73ed8c66a33377cc0aca" "FirefoxSetup62.0.3-win32.exe"
    w_try_7z "$W_TMP/win32" "$W_CACHE/d3dcompiler_47/FirefoxSetup62.0.3-win32.exe" "core/d3dcompiler_47.dll"
    w_try cp "$W_TMP/win32/core/d3dcompiler_47.dll" "$W_SYSTEM32_DLLS/d3dcompiler_47.dll"

    if [ "$W_ARCH" = "win64" ]; then
        w_download ${W_DOWNLOADURLS}/Firefox%20Setup%2062.0.3.exe "721977f36c008af2b637aedd3f1b529f3cfed6feb10f68ebe17469acb1934986" "FirefoxSetup62.0.3-win64.exe"
        w_try_7z "$W_TMP/win64" "$W_CACHE/d3dcompiler_47/FirefoxSetup62.0.3-win64.exe" "core/d3dcompiler_47.dll"
        w_try cp "$W_TMP/win64/core/d3dcompiler_47.dll" "$W_SYSTEM64_DLLS/d3dcompiler_47.dll"
    fi

    w_override_dlls native d3dcompiler_47
}

#----------------------------------------------------------------

w_metadata d3drm dlls \
    title="MS d3drm.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3drm.dll"

load_d3drm()
{
    helper_directx_dl

    w_try_cabextract -d "$W_TMP" -L -F "dxnt.cab" "$W_CACHE"/directx9/$DIRECTX_NAME
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F "d3drm.dll" "$W_TMP/dxnt.cab"

    w_override_dlls native d3drm
}

#----------------------------------------------------------------

w_metadata d3dx9 dlls \
    title="MS d3dx9_??.dll from DirectX 9 redistributable" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx9_43.dll"

load_d3dx9()
{
    helper_directx_Jun2010

    # Kinder, less invasive directx - only extract and override d3dx9_??.dll
    w_try_cabextract -d "$W_TMP" -L -F '*d3dx9*x86*' "$W_CACHE"/directx9/$DIRECTX_NAME
    for x in "$W_TMP"/*.cab; do
      w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'd3dx9*.dll' "$x"
    done
    if test "$W_ARCH" = "win64"; then
        w_try_cabextract -d "$W_TMP" -L -F '*d3dx9*x64*' "$W_CACHE"/directx9/$DIRECTX_NAME
        for x in "$W_TMP"/*x64.cab; do
            w_try_cabextract -d "$W_SYSTEM64_DLLS" -L -F 'd3dx9*.dll' "$x"
        done
    fi

    # For now, not needed, but when Wine starts preferring our builtin dll over native it will be.
    w_override_dlls native d3dx9_24 d3dx9_25 d3dx9_26 d3dx9_27 d3dx9_28 d3dx9_29 d3dx9_30
    w_override_dlls native d3dx9_31 d3dx9_32 d3dx9_33 d3dx9_34 d3dx9_35 d3dx9_36 d3dx9_37
    w_override_dlls native d3dx9_38 d3dx9_39 d3dx9_40 d3dx9_41 d3dx9_42 d3dx9_43
}

#----------------------------------------------------------------

w_metadata d3dx9_24 dlls \
    title="MS d3dx9_24.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx9_24.dll"

load_d3dx9_24()
{
    helper_d3dx9_xx 24
}

#----------------------------------------------------------------

w_metadata d3dx9_25 dlls \
    title="MS d3dx9_25.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx9_25.dll"

load_d3dx9_25()
{
    helper_d3dx9_xx 25
}

#----------------------------------------------------------------

w_metadata d3dx9_26 dlls \
    title="MS d3dx9_26.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx9_26.dll"

load_d3dx9_26()
{
    helper_d3dx9_xx 26
}

#----------------------------------------------------------------

w_metadata d3dx9_27 dlls \
    title="MS d3dx9_27.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx9_27.dll"

load_d3dx9_27()
{
    helper_d3dx9_xx 27
}

#----------------------------------------------------------------

w_metadata d3dx9_28 dlls \
    title="MS d3dx9_28.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx9_28.dll"

load_d3dx9_28()
{
    helper_d3dx9_xx 28
}

#----------------------------------------------------------------

w_metadata d3dx9_29 dlls \
    title="MS d3dx9_29.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx9_29.dll"

load_d3dx9_29()
{
    helper_d3dx9_xx 29
}

#----------------------------------------------------------------

w_metadata d3dx9_30 dlls \
    title="MS d3dx9_30.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx9_30.dll"

load_d3dx9_30()
{
    helper_d3dx9_xx 30
}

#----------------------------------------------------------------

w_metadata d3dx9_31 dlls \
    title="MS d3dx9_31.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx9_31.dll"

load_d3dx9_31()
{
    helper_d3dx9_xx 31
}

#----------------------------------------------------------------

w_metadata d3dx9_32 dlls \
    title="MS d3dx9_32.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx9_32.dll"

load_d3dx9_32()
{
    helper_d3dx9_xx 32
}

#----------------------------------------------------------------

w_metadata d3dx9_33 dlls \
    title="MS d3dx9_33.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx9_33.dll"

load_d3dx9_33()
{
    helper_d3dx9_xx 33
}

#----------------------------------------------------------------

w_metadata d3dx9_34 dlls \
    title="MS d3dx9_34.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx9_34.dll"

load_d3dx9_34()
{
    helper_d3dx9_xx 34
}

#----------------------------------------------------------------

w_metadata d3dx9_35 dlls \
    title="MS d3dx9_35.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx9_35.dll"

load_d3dx9_35()
{
    helper_d3dx9_xx 35
}

#----------------------------------------------------------------

w_metadata d3dx9_36 dlls \
    title="MS d3dx9_36.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx9_36.dll"

load_d3dx9_36()
{
    helper_d3dx9_xx 36
}

#----------------------------------------------------------------

w_metadata d3dx9_37 dlls \
    title="MS d3dx9_37.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx9_37.dll"

load_d3dx9_37()
{
    helper_d3dx9_xx 37
}

#----------------------------------------------------------------

w_metadata d3dx9_38 dlls \
    title="MS d3dx9_38.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx9_38.dll"

load_d3dx9_38()
{
    helper_d3dx9_xx 38
}

#----------------------------------------------------------------

w_metadata d3dx9_39 dlls \
    title="MS d3dx9_39.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx9_39.dll"

load_d3dx9_39()
{
    helper_d3dx9_xx 39
}

#----------------------------------------------------------------

w_metadata d3dx9_40 dlls \
    title="MS d3dx9_40.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx9_40.dll"

load_d3dx9_40()
{
    helper_d3dx9_xx 40
}

#----------------------------------------------------------------

w_metadata d3dx9_41 dlls \
    title="MS d3dx9_41.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx9_41.dll"

load_d3dx9_41()
{
    helper_d3dx9_xx 41
}

#----------------------------------------------------------------

w_metadata d3dx9_42 dlls \
    title="MS d3dx9_42.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx9_42.dll"

load_d3dx9_42()
{
    helper_d3dx9_xx 42
}

#----------------------------------------------------------------

w_metadata d3dx9_43 dlls \
    title="MS d3dx9_43.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx9_43.dll"

load_d3dx9_43()
{
    helper_d3dx9_xx 43
}

#----------------------------------------------------------------

w_metadata d3dx11_42 dlls \
    title="MS d3dx11_42.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx11_42.dll"

load_d3dx11_42()
{
    dllname=d3dx11_42

    helper_directx_Jun2010

    w_try_cabextract -d "$W_TMP" -L -F "*$dllname*x86*" "$W_CACHE"/directx9/$DIRECTX_NAME
    for x in "$W_TMP"/*.cab; do
      w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F "$dllname.dll" "$x"
    done
    if test "$W_ARCH" = "win64"; then
        w_try_cabextract -d "$W_TMP" -L -F "*$dllname*x64*" "$W_CACHE"/directx9/$DIRECTX_NAME
        for x in "$W_TMP"/*x64.cab; do
            w_try_cabextract -d "$W_SYSTEM64_DLLS" -L -F "$dllname.dll" "$x"
        done
    fi

    w_override_dlls native $dllname
}

#----------------------------------------------------------------

w_metadata d3dx11_43 dlls \
    title="MS d3dx11_43.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx11_43.dll"

load_d3dx11_43()
{
    dllname=d3dx11_43

    helper_directx_Jun2010

    w_try_cabextract -d "$W_TMP" -L -F "*$dllname*x86*" "$W_CACHE"/directx9/$DIRECTX_NAME
    for x in "$W_TMP"/*.cab; do
      w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F "$dllname.dll" "$x"
    done
    if test "$W_ARCH" = "win64"; then
        w_try_cabextract -d "$W_TMP" -L -F "*$dllname*x64*" "$W_CACHE"/directx9/$DIRECTX_NAME
        for x in "$W_TMP"/*x64.cab; do
            w_try_cabextract -d "$W_SYSTEM64_DLLS" -L -F "$dllname.dll" "$x"
        done
    fi

    w_override_dlls native $dllname
}

#----------------------------------------------------------------

w_metadata d3dx10 dlls \
    title="MS d3dx10_??.dll from DirectX user redistributable" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx10_33.dll"

load_d3dx10()
{
    helper_directx_Jun2010

    # Kinder, less invasive directx10 - only extract and override d3dx10_??.dll
    w_try_cabextract -d "$W_TMP" -L -F '*d3dx10*x86*' "$W_CACHE"/directx9/$DIRECTX_NAME
    for x in "$W_TMP"/*.cab; do
      w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'd3dx10*.dll' "$x"
    done
    if test "$W_ARCH" = "win64"; then
        w_try_cabextract -d "$W_TMP" -L -F '*d3dx10*x64*' "$W_CACHE"/directx9/$DIRECTX_NAME
        for x in "$W_TMP"/*x64.cab; do
            w_try_cabextract -d "$W_SYSTEM64_DLLS" -L -F 'd3dx10*.dll' "$x"
        done
    fi

    # For now, not needed, but when Wine starts preferring our built-in DLL over native it will be.
    w_override_dlls native d3dx10_33 d3dx10_34 d3dx10_35 d3dx10_36 d3dx10_37
    w_override_dlls native d3dx10_38 d3dx10_39 d3dx10_40 d3dx10_41 d3dx10_42 d3dx10_43
}

#----------------------------------------------------------------

w_metadata d3dx10_43 dlls \
    title="MS d3dx10_43.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dx10_43.dll"

load_d3dx10_43()
{
    dllname=d3dx10_43

    helper_directx_Jun2010

    w_try_cabextract -d "$W_TMP" -L -F "*$dllname*x86*" "$W_CACHE"/directx9/$DIRECTX_NAME
    for x in "$W_TMP"/*.cab; do
      w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F "$dllname.dll" "$x"
    done
    if test "$W_ARCH" = "win64"; then
        w_try_cabextract -d "$W_TMP" -L -F "*$dllname*x64*" "$W_CACHE"/directx9/$DIRECTX_NAME
        for x in "$W_TMP"/*x64.cab; do
            w_try_cabextract -d "$W_SYSTEM64_DLLS" -L -F "$dllname.dll" "$x"
        done
    fi

    w_override_dlls native $dllname
}

#----------------------------------------------------------------

w_metadata d3dxof dlls \
    title="MS d3dxof.dll from DirectX user redistributable" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3dxof.dll"

load_d3dxof()
{
    helper_directx_dl

    w_try_cabextract -d "$W_TMP" -L -F 'dxnt.cab' "$W_CACHE"/directx9/$DIRECTX_NAME
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'd3dxof.dll' "$W_TMP/dxnt.cab"

    w_override_dlls native d3dxof
}

#----------------------------------------------------------------

w_metadata dbghelp dlls \
    title="MS dbghelp" \
    publisher="Microsoft" \
    year="2008" \
    media="download" \
    file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/dbghelp.dll"

load_dbghelp()
{
    helper_winxpsp3 i386/dbghelp.dll

    w_try cp -f "$W_TMP"/i386/dbghelp.dll "$W_SYSTEM32_DLLS"

    w_override_dlls native dbghelp
}

#----------------------------------------------------------------

w_metadata devenum dlls \
    title="MS devenum.dll from DirectX user redistributable" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/devenum.dll"

load_devenum()
{
    helper_directx_dl

    w_try_cabextract -d "$W_TMP" -L -F 'dxnt.cab' "$W_CACHE/directx9/$DIRECTX_NAME"
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'devenum.dll' "$W_TMP/dxnt.cab"
    w_override_dlls native devenum
    w_try_regsvr devenum.dll
}

#----------------------------------------------------------------

w_metadata dinput dlls \
    title="MS dinput.dll; breaks mouse, use only on Rayman 2 etc." \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/dinput.dll"

load_dinput()
{
    helper_directx_dl

    w_try_cabextract -d "$W_TMP" -L -F 'dxnt.cab' "$W_CACHE"/directx9/$DIRECTX_NAME
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dinput.dll' "$W_TMP/dxnt.cab"
    w_override_dlls native dinput
    w_try_regsvr dinput
}

#----------------------------------------------------------------

w_metadata dinput8 dlls \
    title="MS DirectInput 8 from DirectX user redistributable" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/dinput8.dll"

load_dinput8()
{
    helper_directx_dl

    w_try_cabextract -d "$W_TMP" -L -F 'dxnt.cab' "$W_CACHE"/directx9/$DIRECTX_NAME
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dinput8.dll' "$W_TMP/dxnt.cab"

    # Don't try to register native dinput8; it doesn't export DllRegisterServer().
    w_try_regsvr dinput8
    w_override_dlls native dinput8
}

#----------------------------------------------------------------

w_metadata directmusic dlls \
    title="MS DirectMusic from DirectX user redistributable" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/dmusic.dll"

load_directmusic()
{
    # Untested. Based off https://bugs.winehq.org/show_bug.cgi?id=4805 and https://bugs.winehq.org/show_bug.cgi?id=24911

    w_warn "You can specify individual DirectMusic verbs instead. e.g. 'winetricks dmsynth dmusic'"

    w_call dmband
    w_call dmcompos
    w_call dmime
    w_call dmloader
    w_call dmscript
    w_call dmstyle
    w_call dmsynth
    w_call dmusic
    w_call dmusic32
    w_call dsound
    w_call dswave

    # FIXME: dxnt.cab doesn't contain this DLL. Is this really needed?
    w_override_dlls native streamci
}

#----------------------------------------------------------------

w_metadata directshow dlls \
    title="DirectShow runtime DLLs (amstream, qasf, qcap, qdvd, qedit, quartz)" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe"

load_directshow()
{
    w_warn "You can specify individual DirectShow verbs instead. e.g. 'winetricks quartz'"

    w_call amstream
    w_call qasf
    w_call qcap
    w_call qdvd
    w_call qedit
    w_call quartz
}

#----------------------------------------------------------------

w_metadata directplay dlls \
    title="MS DirectPlay from DirectX user redistributable" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/dplayx.dll"

load_directplay()
{
    helper_directx_dl

    w_try_cabextract -d "$W_TMP" -L -F dxnt.cab "$W_CACHE"/directx9/$DIRECTX_NAME
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dplaysvr.exe' "$W_TMP/dxnt.cab"
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dplayx.dll' "$W_TMP/dxnt.cab"
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dpnet.dll' "$W_TMP/dxnt.cab"
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dpnhpast.dll' "$W_TMP/dxnt.cab"
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dpnsvr.exe' "$W_TMP/dxnt.cab"
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dpwsockx.dll' "$W_TMP/dxnt.cab"

    w_override_dlls native dplayx dpnet dpnhpast dpnsvr.exe dpwsockx

    w_try_regsvr dplayx.dll
    w_try_regsvr dpnet.dll
    w_try_regsvr dpnhpast.dll
}

#----------------------------------------------------------------

w_metadata directx9 dlls \
    title="MS DirectX 9 (Deprecated, no-op)" \
    publisher="Microsoft" \
    year="2010" \
    media="download"

load_directx9()
{
    # There are 54 as of 2019/04/23, so listing them all (especially in GUI) would be hard.
    # Besides, that would probably encourage people to install more native stuff than necessary.
    w_warn "directx9 is deprecated. Please install individual directx components (e.g., \`$0 d3dx9\`) instead."
}

#----------------------------------------------------------------

w_metadata dpvoice dlls \
    title="Microsoft dpvoice dpvvox dpvacm Audio dlls" \
    publisher="Microsoft" \
    year="2002" \
    media="download" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/dpvoice.dll" \
    installed_file2="$W_SYSTEM32_DLLS_WIN/dpvvox.dll" \
    installed_file2="$W_SYSTEM32_DLLS_WIN/dpvacm.dll"

load_dpvoice()
{
    helper_directx_dl

    w_try_cabextract -d "$W_TMP" -L -F 'dxnt.cab' "$W_CACHE"/directx9/$DIRECTX_NAME
    for x in "$W_TMP"/*.cab; do
      w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dpvoice.dll' "$x"
      w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dpvvox.dll' "$x"
      w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dpvacm.dll' "$x"
    done
    w_override_dlls native dpvoice dpvvox dpvacm
    w_try_regsvr dpvoice.dll
    w_try_regsvr dpvvox.dll
    w_try_regsvr dpvacm.dll
}

#----------------------------------------------------------------

w_metadata dsdmo dlls \
    title="MS dsdmo.dll" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/dsdmo.dll"

load_dsdmo()
{
    helper_directx_dl
    mkdir "$W_CACHE"/dsdmo   # kludge so test -f $file1 works

    w_try_cabextract -d "$W_TMP" -L -F dxnt.cab "$W_CACHE"/directx9/$DIRECTX_NAME
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dsdmo.dll' "$W_TMP/dxnt.cab"
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dsdmoprp.dll' "$W_TMP/dxnt.cab"
    w_try_regsvr dsdmo.dll
    w_try_regsvr dsdmoprp.dll
}

#----------------------------------------------------------------

w_metadata dxsdk_nov2006 apps \
    title="MS DirectX SDK, November 2006 (developers only)" \
    publisher="Microsoft" \
    year="2006" \
    media="download" \
    file1="dxsdk_aug2006.exe" \
    installed_file1="$W_PROGRAMS_X86_WIN/Microsoft DirectX SDK (August 2006)/Lib/x86/d3d10.lib"

load_dxsdk_nov2006()
{
    w_download ${W_DOWNLOADURLS}/dxsdk_aug2006.exe ab8d7d895089a88108d4148ef0f7e214b7a23c1ee9ba720feca78c7d4ca16c00

    # dxview.dll uses mfc42u while registering
    w_call mfc42

    w_try_cabextract "$W_CACHE"/dxsdk_nov2006/dxsdk_aug2006.exe
    w_try_unzip "$W_TMP" dxsdk.exe
    w_try_cd "$W_TMP"
    w_try "$WINE" msiexec /i Microsoft_DirectX_SDK.msi $W_UNATTENDED_SLASH_Q
}

#----------------------------------------------------------------

w_metadata dxsdk_jun2010 apps \
    title="MS DirectX SDK, June 2010 (developers only)" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="DXSDK_Jun10.exe" \
    installed_file1="$W_PROGRAMS_X86_WIN/Microsoft DirectX SDK (June 2010)/Lib/x86/d3d11.lib"

load_dxsdk_jun2010()
{
    w_download ${W_DOWNLOADURLS}/DXSDK_Jun10.exe 9f818a977c32b254af5d649a4cec269ed8762f8a49ae67a9f01101a7237ae61a

    # Without dotnet20, install aborts halfway through
    w_call dotnet20

    w_try_cd "$W_TMP"
    w_try "$WINE" "$W_CACHE"/dxsdk_jun2010/DXSDK_Jun10.exe ${W_OPT_UNATTENDED:+/U}
}

#----------------------------------------------------------------

w_metadata dxtrans dlls \
    title="MS dxtrans.dll" \
    publisher="Microsoft" \
    year="2002" \
    media="download" \
    file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/dxtrans.dll" \

load_dxtrans()
{
    helper_winxpsp3 i386/dxtrans.dl_
    w_try_cabextract --directory="$W_SYSTEM32_DLLS" "$W_TMP"/i386/dxtrans.dl_
    w_override_dlls native,builtin dxtrans
    w_try_regsvr dxtrans.dll
}

#----------------------------------------------------------------

# $1 - dxvk archive name (required)
# $2 - minimum Wine version (required)
# $3 - minimum Vulkan API version (required)
# $4 - [dxgi,][d3d9,][d3d10core,][d3d10,]d3d11 (required)
helper_dxvk_d9vk()
{
    _W_package_archive="${1}"
    _W_min_wine_version="${2}"
    _W_min_vulkan_version="${3}"
    _W_dll_overrides="$(echo "${4}" | sed 's/,/ /g')"

    _W_supported_overrides="dxgi d3d9 d3d10core d3d10 d3d11"
    _W_invalid_overrides="$(echo "${_W_dll_overrides}" | awk -vvalid_overrides_regex="$(echo "${_W_supported_overrides}" | sed 's/ /|/g')" '{ gsub(valid_overrides_regex,""); sub("[ ]*",""); print $0 }')"
    if [ "${_W_invalid_overrides}" != "" ]; then
        w_die "parameter (4) unsupported dll override: '${_W_invalid_overrides}' ; supported dll overrides: ${_W_supported_overrides}"
    fi

    _W_dll_overrides="$(echo "${_W_dll_overrides}" | sed 's/d3d10 /&d3d10_1 /')"

    case "${_W_package_archive}" in
        d9vk*)
            # dvk9 repository, for d3d9/d3d10/d3d11 support
            _W_repository="Joshua-Ashton/d9vk"
            ;;
        dxvk*)
            # dxvk repository, for d3d9/d3d10/d3d11 support
            _W_repository="doitsujin/dxvk"
            ;;
        *)
            w_die "parameter (1): unsupported package archive repository: '${_W_package_archive}'; supported: d9vk dxvk"
            ;;
    esac

    case "${_W_package_archive}" in
        *master*)
            _W_package_dir="build/dxvk-release"
            _W_package_version="master"
            w_warn "Using master ${_W_repository} build"
            ;;
        *)
            _W_package_dir="${_W_package_archive%.tar.gz}"
            _W_package_version="${_W_package_dir#*-}"
            w_warn "Please refer to ${_W_repository#*/} version ${_W_package_version} release notes... See: https://github.com/${_W_repository}/releases/tag/${_W_package_version}"
            ;;
    esac
    w_warn "Please refer to current dxvk base graphics driver requirements... See: https://github.com/doitsujin/dxvk/wiki/Driver-support"

    if ! w_wine_version_in ",${_W_min_wine_version}" ; then
        # shellcheck disable=SC2140
        w_warn "${_W_repository#*/} ${_W_package_version} does not support wine version ${_wine_version_stripped} . "\
            "${_W_repository#*/} ${_W_package_version} requires wine version ${_W_min_wine_version} (or newer). "\
            "Vulkan ${_W_min_vulkan_version} API (or newer) support is recommended."
    fi

    if [ "${_W_package_archive##*.}" = "zip" ]; then
        w_try_unzip "$W_TMP" "${W_CACHE}/${W_PACKAGE}/${_W_package_archive}"
    else
        w_try_cd "${W_TMP}"
        w_try tar -zxf "${W_CACHE}/${W_PACKAGE}/${_W_package_archive}"
    fi

    for _W_dll in ${_W_dll_overrides}; do
        w_try mv "${W_TMP}/${_W_package_dir}/x32/${_W_dll}.dll" "${W_SYSTEM32_DLLS}/"
        [ "${_W_dll}" = "d3d9" ] && _W_d3d9_support="1"
    done
    if test "${W_ARCH}" = "win64"; then
        for _W_dll in ${_W_dll_overrides}; do
            w_try mv "${W_TMP}/${_W_package_dir}/x64/${_W_dll}.dll" "${W_SYSTEM64_DLLS}/"
        done
    fi
    # shellcheck disable=SC2086
    w_override_dlls native ${_W_dll_overrides}
    if [ -n "${_W_d3d9_support}" ]; then
        w_call d3dcompiler_43
        w_call d3dx9
    fi

    unset _W_d3d9_support _W_dll _W_dll_overrides _W_invalid_overrides _W_min_vulkan_version _W_min_wine_version \
        _W_package_archive _W_package_dir _W_package_version \
        _W_repository _W_supported_overrides
}


#----------------------------------------------------------------



w_metadata d9vk040 dlls \
    title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (0.40.1)" \
    publisher="Joshua Ashton" \
    year="2019" \
    media="download" \
    file1="d9vk-0.40.1.tar.gz" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3d9.dll" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3d10.dll" \
    installed_file2="$W_SYSTEM32_DLLS_WIN/d3d10_1.dll" \
    installed_file3="$W_SYSTEM32_DLLS_WIN/d3d10core.dll" \
    installed_file4="$W_SYSTEM32_DLLS_WIN/d3d11.dll" \
    installed_file5="$W_SYSTEM32_DLLS_WIN/dxgi.dll"

load_d9vk040()
{
    # https://github.com/Joshua-Ashton/d9vk
    w_download "${W_DOWNLOADURLS}/d9vk-0.40.1.tar.gz" 6bfcf05d68207b140dbfaa938f8e3807d938466682b531d6daa36b22fa0a6d03
    helper_dxvk_d9vk "$file1" "4.5" "1.1.104" "dxgi,d3d9,d3d10core,d3d10,d3d11"
}

#----------------------------------------------------------------

w_metadata d9vk dlls \
    title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (latest)" \
    publisher="Joshua Ashton" \
    year="2019" \
    media="download" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3d9.dll" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3d10.dll" \
    installed_file2="$W_SYSTEM32_DLLS_WIN/d3d10_1.dll" \
    installed_file3="$W_SYSTEM32_DLLS_WIN/d3d10core.dll" \
    installed_file4="$W_SYSTEM32_DLLS_WIN/d3d11.dll" \
    installed_file5="$W_SYSTEM32_DLLS_WIN/dxgi.dll"

load_d9vk()
{
    # https://github.com/Joshua-Ashton/d9vk
    _W_d9vk_version="$(w_get_github_latest_prerelease Joshua-Ashton d9vk)"
    _W_d9vk_version="${_W_d9vk_version#v}"
    w_linkcheck_ignore=1 w_download "https://github.com/Joshua-Ashton/d9vk/releases/download/${_W_d9vk_version}/d9vk-${_W_d9vk_version}.tar.gz"
    helper_dxvk_d9vk "d9vk-${_W_d9vk_version}.tar.gz" "4.5" "1.1.104" "dxgi,d3d9,d3d10core,d3d10,d3d11"
    unset _W_d9vk_version
}


#----------------------------------------------------------------

w_metadata dxvk160 dlls \
    title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (1.6)" \
    publisher="Philip Rebohle" \
    year="2017" \
    media="download" \
    file1="dxvk-1.6.tar.gz" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3d9.dll" \
    installed_file2="$W_SYSTEM32_DLLS_WIN/d3d10core.dll" \
    installed_file3="$W_SYSTEM32_DLLS_WIN/d3d11.dll" \
    installed_file4="$W_SYSTEM32_DLLS_WIN/dxgi.dll"

load_dxvk160()
{
    # https://github.com/doitsujin/dxvk
    w_download "${W_DOWNLOADURLS}/v1.6/dxvk-1.6.tar.gz" a493e0802e02629244672c44ad92c40fa0813b38908677ae14ee07feefcf7227
    helper_dxvk_d9vk "$file1" "5.3" "1.1.113" "dxgi,d3d9,d3d10core,d3d11"
}

#----------------------------------------------------------------

w_metadata dxvk dlls \
    title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (latest)" \
    publisher="Philip Rebohle" \
    year="2017" \
    media="download" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3d9.dll" \
    installed_file2="$W_SYSTEM32_DLLS_WIN/d3d10core.dll" \
    installed_file3="$W_SYSTEM32_DLLS_WIN/d3d11.dll" \
    installed_file4="$W_SYSTEM32_DLLS_WIN/dxgi.dll"

load_dxvk()
{
    # https://github.com/doitsujin/dxvk
    _W_dxvk_version="$(w_get_github_latest_release doitsujin dxvk)"
    _W_dxvk_version="${_W_dxvk_version#v}"
    w_linkcheck_ignore=1 w_download "https://github.com/doitsujin/dxvk/releases/download/v${_W_dxvk_version}/dxvk-${_W_dxvk_version}.tar.gz"
    helper_dxvk_d9vk "dxvk-${_W_dxvk_version}.tar.gz" "5.3" "1.1.113" "dxgi,d3d9,d3d10core,d3d11"
    unset _W_dxvk_version
}

#----------------------------------------------------------------

w_metadata dxvk_master dlls \
    title="Vulkan-based D3D9/D3D10/D3D11 implementation for Linux / Wine (master)" \
    publisher="Philip Rebohle" \
    year="2017" \
    media="download" \
    file1="dxvk_master.zip" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3d9.dll" \
    installed_file2="$W_SYSTEM32_DLLS_WIN/d3d10core.dll" \
    installed_file3="$W_SYSTEM32_DLLS_WIN/d3d11.dll" \
    installed_file4="$W_SYSTEM32_DLLS_WIN/dxgi.dll"

load_dxvk_master()
{
    # https://git.froggi.es/doitsujin/dxvk
    # FIXME: Delete cached file, when verb is forced. Gitlab artifacts do not supply any version/commit hash information.
    if test "$WINETRICKS_FORCE" = 1 && test -f "${W_CACHE}/${W_PACKAGE}/${file1}"; then
        w_try rm -f "${W_CACHE}/${W_PACKAGE}/${file1}"
    fi
    w_linkcheck_ignore=1 w_download_to "${W_CACHE}/${W_PACKAGE}" "https://git.froggi.es/doitsujin/dxvk/-/jobs/artifacts/master/download?job=dxvk" "" "dxvk_master.zip"
    helper_dxvk_d9vk "$file1" "5.3" "1.1.113" "dxgi,d3d9,d3d10core,d3d11"
}

#----------------------------------------------------------------

w_metadata dmusic32 dlls \
    title="MS dmusic32.dll from DirectX user redistributable" \
    publisher="Microsoft" \
    year="2006" \
    media="download" \
    file1="../directx9/directx_apr2006_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/dmusic32.dll"

load_dmusic32()
{
    w_download_to directx9 ${W_DOWNLOADURLS}/directx_apr2006_redist.exe dd8c3d401efe4561b67bd88475201b2f62f43cd23e4acc947bb34a659fa74952

    w_try_cabextract -d "$W_TMP" -F DirectX.cab "$W_CACHE"/directx9/directx_apr2006_redist.exe
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F dmusic32.dll "$W_TMP"/DirectX.cab

    w_override_dlls native dmusic32
}

#----------------------------------------------------------------

w_metadata dmband dlls \
    title="MS dmband.dll from DirectX user redistributable" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/dmband.dll"

load_dmband()
{
    helper_directx_dl

    w_try_cabextract -d "$W_TMP" -L -F dxnt.cab "$W_CACHE"/directx9/$DIRECTX_NAME
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dmband.dll' "$W_TMP/dxnt.cab"

    w_override_dlls native dmband
    w_try_regsvr dmband.dll
}

#----------------------------------------------------------------

w_metadata dmcompos dlls \
    title="MS dmcompos.dll from DirectX user redistributable" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/dmcompos.dll"

load_dmcompos()
{
    helper_directx_dl

    w_try_cabextract -d "$W_TMP" -L -F dxnt.cab "$W_CACHE"/directx9/$DIRECTX_NAME
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dmcompos.dll' "$W_TMP/dxnt.cab"

    w_override_dlls native dmcompos
    w_try_regsvr dmcompos.dll
}

#----------------------------------------------------------------

w_metadata dmime dlls \
    title="MS dmime.dll from DirectX user redistributable" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/dmime.dll"

load_dmime()
{
    helper_directx_dl

    w_try_cabextract -d "$W_TMP" -L -F dxnt.cab "$W_CACHE"/directx9/$DIRECTX_NAME
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dmime.dll' "$W_TMP/dxnt.cab"

    w_override_dlls native dmime
    w_try_regsvr dmime.dll
}

#----------------------------------------------------------------

w_metadata dmloader dlls \
    title="MS dmloader.dll from DirectX user redistributable" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/dmloader.dll"

load_dmloader()
{
    helper_directx_dl

    w_try_cabextract -d "$W_TMP" -L -F dxnt.cab "$W_CACHE"/directx9/$DIRECTX_NAME
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dmloader.dll' "$W_TMP/dxnt.cab"

    w_override_dlls native dmloader
    w_try_regsvr dmloader.dll
}

#----------------------------------------------------------------

w_metadata dmscript dlls \
    title="MS dmscript.dll from DirectX user redistributable" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/dmscript.dll"

load_dmscript()
{
    helper_directx_dl

    w_try_cabextract -d "$W_TMP" -L -F dxnt.cab "$W_CACHE"/directx9/$DIRECTX_NAME
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dmscript.dll' "$W_TMP/dxnt.cab"

    w_override_dlls native dmscript
    w_try_regsvr dmscript.dll
}

#----------------------------------------------------------------

w_metadata dmstyle dlls \
    title="MS dmstyle.dll from DirectX user redistributable" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/dmstyle.dll"

load_dmstyle()
{
    helper_directx_dl

    w_try_cabextract -d "$W_TMP" -L -F dxnt.cab "$W_CACHE"/directx9/$DIRECTX_NAME
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dmstyle.dll' "$W_TMP/dxnt.cab"

    w_override_dlls native dmstyle
    w_try_regsvr dmstyle.dll
}

#----------------------------------------------------------------

w_metadata dmsynth dlls \
    title="MS dmsynth.dll from DirectX user redistributable" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/dmsynth.dll"

load_dmsynth()
{
    helper_directx_dl

    w_try_cabextract -d "$W_TMP" -L -F dxnt.cab "$W_CACHE"/directx9/$DIRECTX_NAME
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dmsynth.dll' "$W_TMP/dxnt.cab"

    w_override_dlls native dmsynth
    w_try_regsvr dmsynth.dll
}

#----------------------------------------------------------------

w_metadata dmusic dlls \
    title="MS dmusic.dll from DirectX user redistributable" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/dmusic.dll"

load_dmusic()
{
    helper_directx_dl

    w_try_cabextract -d "$W_TMP" -L -F dxnt.cab "$W_CACHE"/directx9/$DIRECTX_NAME
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dmusic.dll' "$W_TMP/dxnt.cab"

    w_override_dlls native dmusic
    w_try_regsvr dmusic.dll
}

#----------------------------------------------------------------

w_metadata dswave dlls \
    title="MS dswave.dll from DirectX user redistributable" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/dswave.dll"

load_dswave()
{
    helper_directx_dl

    w_try_cabextract -d "$W_TMP" -L -F dxnt.cab "$W_CACHE"/directx9/$DIRECTX_NAME
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dswave.dll' "$W_TMP/dxnt.cab"

    w_override_dlls native dswave
    w_try_regsvr dswave.dll
}

#----------------------------------------------------------------

w_metadata dotnet11 dlls \
    title="MS .NET 1.1" \
    publisher="Microsoft" \
    year="2003" \
    media="download" \
    conflicts="dotnet20sdk" \
    file1="dotnetfx.exe" \
    installed_file1="c:/windows/Microsoft.NET/Framework/v1.1.4322/ndpsetup.ico"

load_dotnet11()
{
    # The installer itself doesn't support 64-bit
    w_package_unsupported_win64

    # https://www.microsoft.com/en-us/download/details.aspx?id=26
    w_download ${W_DOWNLOADURLS}/dotnetfx.exe ba0e58ec93f2ffd54fc7c627eeca9502e11ab3c6fc85dcbeff113bd61d995bce

    w_call remove_mono
    w_call corefonts
    w_call fontfix

    w_try_cd "$W_CACHE/$W_PACKAGE"
    # Use builtin regsvcs.exe to work around https://bugs.winehq.org/show_bug.cgi?id=25120
    if test $W_OPT_UNATTENDED; then
        WINEDLLOVERRIDES="regsvcs.exe=b" w_ahk_do "
            SetTitleMatchMode, 2
            run, dotnetfx.exe /q /C:\"install /q\"

            Loop
            {
                sleep 1000
                ifwinexist, Fatal error, Failed to delay load library
                {
                    WinClose, Fatal error, Failed to delay load library
                    continue
                }
                Process, exist, dotnetfx.exe
                dotnet_pid = %ErrorLevel%  ; Save the value immediately since ErrorLevel is often changed.
                if dotnet_pid = 0
                {
                    break
                }
            }
        "
    else
        WINEDLLOVERRIDES="regsvcs.exe=b" w_try "$WINE" dotnetfx.exe
    fi

    w_override_dlls native mscorwks

    W_NGEN_CMD="w_try $WINE $W_DRIVE_C/windows/Microsoft.NET/Framework/v1.1.4322/ngen.exe executequeueditems"
}

verify_dotnet11()
{
    w_dotnet_verify dotnet11
}

#----------------------------------------------------------------

w_metadata dotnet11sp1 dlls \
    title="MS .NET 1.1 SP1" \
    publisher="Microsoft" \
    year="2004" \
    media="download" \
    file1="NDP1.1sp1-KB867460-X86.exe" \
    installed_file1="c:/windows/Microsoft.NET/Framework/v1.1.4322/CONFIG/web_hightrust.config.default"

load_dotnet11sp1()
{
    # The installer itself doesn't support 64-bit
    w_package_unsupported_win64

    w_download ${W_DOWNLOADURLS}/NDP1.1sp1-KB867460-X86.exe 2c0a35409ff0873cfa28b70b8224e9aca2362241c1f0ed6f622fef8d4722fd9a

    w_call remove_mono
    w_call dotnet11

    w_try_cd "$W_CACHE/$W_PACKAGE"
    # Use builtin regsvcs.exe to work around https://bugs.winehq.org/show_bug.cgi?id=25120
    if test $W_OPT_UNATTENDED; then
        WINEDLLOVERRIDES="regsvcs.exe=b" w_ahk_do "
            SetTitleMatchMode, 2
            run, NDP1.1sp1-KB867460-X86.exe /q /C:"install /q"

            Loop
            {
                sleep 1000
                ifwinexist, Fatal error, Failed to delay load library
                {
                    WinClose, Fatal error, Failed to delay load library
                    continue
                }
                Process, exist, dotnetfx.exe
                dotnet_pid = %ErrorLevel%  ; Save the value immediately since ErrorLevel is often changed.
                if dotnet_pid = 0
                {
                    break
                }
            }
        "
    else
        WINEDLLOVERRIDES="regsvcs.exe=b" w_try "$WINE" "$W_CACHE"/dotnet11sp1/NDP1.1sp1-KB867460-X86.exe
    fi

    w_override_dlls native mscorwks

    W_NGEN_CMD="w_try $WINE $W_DRIVE_C/windows/Microsoft.NET/Framework/v1.1.4322/ngen.exe executequeueditems"
}

verify_dotnet11sp1()
{
    w_dotnet_verify dotnet11sp1
}

#----------------------------------------------------------------

w_metadata dotnet20 dlls \
    title="MS .NET 2.0" \
    publisher="Microsoft" \
    year="2006" \
    media="download" \
    conflicts="dotnet20sp1 dotnet20sp2 dotnet30sp1 dotnet35" \
    file1="dotnetfx.exe" \
    installed_file1="c:/windows/Microsoft.NET/Framework/v2.0.50727/MSBuild.exe"

load_dotnet20()
{
    w_call remove_mono
    w_call fontfix

    if [ "$W_ARCH" = "win32" ]; then
        # https://www.microsoft.com/en-us/download/details.aspx?id=19
        w_download ${W_DOWNLOADURLS}/dotnetfx.exe 46693d9b74d12454d117cc61ff2e9481cabb100b4d74eb5367d3cf88b89a0e71

        # Needed for https://bugs.winehq.org/show_bug.cgi?id=12401
        w_set_winver win2k

        # if dotnet11 if installed there is a warning dialog, but it still verifies
        # dotnet11 doesn't work on 64-bit, so no need to run there
        w_try_cd "$W_CACHE/$W_PACKAGE"
        if [ -n "${W_OPT_UNATTENDED}" ]; then
            w_ahk_do "
                SetTitleMatchMode, 2
                ; FIXME: this isn't silent?
                run, dotnetfx.exe /q /c:\"install.exe /q\"

                Loop
                {
                    sleep 1000
                    ifwinexist, .NET Framework Initialization Error
                    {
                        WinClose, .NET Framework Initialization Error
                        continue
                    }

                    Process, exist, dotnetfx.exe
                    dotnet_pid = %ErrorLevel%
                    if dotnet_pid = 0
                    {
                        break
                    }
                }
            "
        else
            w_try_ms_installer "$WINE" dotnetfx.exe ${W_OPT_UNATTENDED:+/q /c:"install.exe /q"}
        fi

        w_set_winver 'default'

        # We can't stop installing dotnet20 in win2k mode until Wine supports
        # reparse/junction points
        # (see https://bugs.winehq.org/show_bug.cgi?id=10467#c57 )
        # so for now just remove the bogus msvc*80.dll files it installs.
        # See also https://bugs.winehq.org/show_bug.cgi?id=16577
        # This affects Victoria 2 demo, see https://forum.paradoxplaza.com/forum/showthread.php?p=11523967
        rm -f "$W_SYSTEM32_DLLS"/msvc?80.dll
    elif [ "$W_ARCH" = "win64" ]; then
        w_download ${W_DOWNLOADURLS}/NetFx64.exe 7ea86dca8eeaedcaa4a17370547ca2cea9e9b6774972b8e03d2cb1fb0e798669

        # validates successfully in win7 mode wine-3.19, so not setting winversion
        w_try_cd "$W_CACHE"/"$W_PACKAGE"
        w_try "$WINE" NetFx64.exe ${W_OPT_UNATTENDED:+/q /c:"install.exe /q"}
    fi

    w_override_dlls native mscorwks

    W_NGEN_CMD="w_try $WINE $W_DRIVE_C/windows/Microsoft.NET/Framework/v2.0.50727/ngen.exe executequeueditems"
}

verify_dotnet20()
{
    w_dotnet_verify dotnet20
}

#----------------------------------------------------------------

w_metadata dotnet20sdk apps \
    title="MS .NET 2.0 SDK" \
    publisher="Microsoft" \
    year="2006" \
    media="download" \
    conflicts="dotnet11 dotnet20sp1 dotnet20sp2 dotnet30 dotnet40" \
    file1="setup.exe" \
    installed_file1="$W_PROGRAMS_X86_WIN/Microsoft.NET/SDK/v2.0/Bin/cordbg.exe"

load_dotnet20sdk()
{
    w_package_unsupported_win64

    # https://www.microsoft.com/en-us/download/details.aspx?id=19988
    w_download ${W_DOWNLOADURLS}/setup.exe 1d7337bfbb2c65f43c82d188688ce152af403bcb67a2cc2a3cc68a580ecd8200

    w_call remove_mono

    w_call dotnet20

    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_ahk_do "
        SetTitleMatchMode, 2
        run, setup.exe ${W_OPT_UNATTENDED:+/q /c:"install.exe /q"}

        Loop
        {
            sleep 1000
            ifwinexist, Microsoft Document Explorer, Application Data folder
            {
                WinClose, Microsoft Document Explorer, Application Data folder
                continue
            }
            ifwinexist, Microsoft CLR Debugger, Application Data folder
            {
                WinClose, Microsoft CLR Debugger, Application Data folder
                continue
            }
            ; FIXME: only appears if dotnet30sp1 is run first?
            ifwinexist, Microsoft .NET Framework 2.0 SDK Setup, This wizard will guide
            {
                ControlClick, Button22, Microsoft .NET Framework 2.0 SDK Setup
                Winwait, Microsoft .NET Framework 2.0 SDK Setup, By clicking
                sleep 100
                ControlClick, Button21
                sleep 100
                ControlClick, Button18
                WinWait, Microsoft .NET Framework 2.0 SDK Setup, Select from
                sleep 100
                ControlClick, Button12
                WinWait, Microsoft .NET Framework 2.0 SDK Setup, Type the path
                sleep 100
                ControlClick, Button8
                WinWait, Microsoft .NET Framework 2.0 SDK Setup, successfully installed
                sleep 100
                ControlClick, Button2
                sleep 100
            }
            Process, exist, setup.exe
            dotnet_pid = %ErrorLevel%
            if dotnet_pid = 0
            {
                break
            }
        }
    "

}

#----------------------------------------------------------------

w_metadata dotnet20sp1 dlls \
    title="MS .NET 2.0 SP1" \
    publisher="Microsoft" \
    year="2008" \
    media="download" \
    conflicts="dotnet20sp2" \
    file1="NetFx20SP1_x86.exe" \
    installed_file1="c:/windows/dotnet20sp1.installed.workaround"

load_dotnet20sp1()
{
    w_call remove_mono

    # Not sure when exactly it was fixed, but it works with 4.0+, and doesn't in 3.0
    # Given that 3.x is deprecated, not worth looking into.
    # See https://github.com/Winetricks/winetricks/pull/1271
    # https://bugs.winehq.org/show_bug.cgi?id=47484, et al
    if w_wine_version_in ,4.0 ; then
        WINEDLLOVERRIDES="regsvcs.exe,mscorsvw.exe=b;$WINEDLLOVERRIDES"
        export WINEDLLOVERRIDES
    else
        WINEDLLOVERRIDES="ngen.exe,regsvcs.exe,mscorsvw.exe=b;$WINEDLLOVERRIDES"
        export WINEDLLOVERRIDES
    fi

    if [ "$W_ARCH" = "win32" ]; then
        # https://www.microsoft.com/en-us/download/details.aspx?id=16614
        w_download ${W_DOWNLOADURLS}/NetFx20SP1_x86.exe c36c3a1d074de32d53f371c665243196a7608652a2fc6be9520312d5ce560871
        exe="NetFx20SP1_x86.exe"

        w_warn "Setting windows version so installer works"
        w_set_winver win2k
    elif [ "$W_ARCH" = "win64" ]; then
        # https://www.microsoft.com/en-us/download/details.aspx?id=6041
        w_download ${W_DOWNLOADURLS}/NetFx20SP1_x64.exe 1731e53de5f48baae0963677257660df1329549e81c48b4d7db7f7f3f2329aab
        exe="NetFx20SP1_x64.exe"

        w_warn "Setting windows version so installer works"
        w_set_winver winxp
    fi

    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try_ms_installer "$WINE" "$exe" ${W_OPT_UNATTENDED:+/q}

    if [ "$W_ARCH" = "win32" ]; then
        # We can't stop installing dotnet20sp1 in win2k mode until Wine supports
        # reparse/junction points
        # (see https://bugs.winehq.org/show_bug.cgi?id=10467#c57 )
        # so for now just remove the bogus msvc*80.dll files it installs.
        # See also https://bugs.winehq.org/show_bug.cgi?id=16577
        # This affects Victoria 2 demo, see https://forum.paradoxplaza.com/forum/showthread.php?p=11523967
        rm -f "$W_SYSTEM32_DLLS"/msvc?80.dll

    fi

    w_set_winver 'default'

    W_NGEN_CMD="w_try $WINE $W_DRIVE_C/windows/Microsoft.NET/Framework/v2.0.50727/ngen.exe executequeueditems"

    w_override_dlls native mscorwks

    # Installs the same file(name)s as dotnet35sp1, let users install dotnet35sp1 after dotnet20sp1
    w_try touch "${W_WINDIR_UNIX}/dotnet20sp1.installed.workaround"
}

verify_dotnet20sp1()
{
    w_dotnet_verify dotnet20sp1
}

#----------------------------------------------------------------

w_metadata dotnet20sp2 dlls \
    title="MS .NET 2.0 SP2" \
    publisher="Microsoft" \
    year="2009" \
    media="download" \
    conflicts="dotnet11" \
    file1="NetFx20SP2_x86.exe" \
    installed_file1="c:/windows/winsxs/manifests/x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.3053_x-ww_b80fa8ca.cat"

load_dotnet20sp2()
{
    w_call remove_mono

    # Not sure when exactly it was fixed, but it works with 4.0+, and doesn't in 3.0
    # Given that 3.x is deprecated, not worth looking into.
    # See https://github.com/Winetricks/winetricks/pull/1271
    # https://bugs.winehq.org/show_bug.cgi?id=47484, et al
    if w_wine_version_in ,4.0 ; then
        WINEDLLOVERRIDES="regsvcs.exe,mscorsvw.exe=b;$WINEDLLOVERRIDES"
        export WINEDLLOVERRIDES
    else
        WINEDLLOVERRIDES="ngen.exe,regsvcs.exe,mscorsvw.exe=b;$WINEDLLOVERRIDES"
        export WINEDLLOVERRIDES
    fi
    w_warn "Setting windows version so installer works"
    w_set_winver winxp

    if [ "$W_ARCH" = "win32" ]; then
        # https://www.microsoft.com/en-us/download/details.aspx?id=1639
        w_download ${W_DOWNLOADURLS}/NetFx20SP2_x86.exe 6e3f363366e7d0219b7cb269625a75d410a5c80d763cc3d73cf20841084e851f
        exe="NetFx20SP2_x86.exe"
    elif [ "$W_ARCH" = "win64" ]; then
        # https://www.microsoft.com/en-us/download/details.aspx?id=1639
        w_download ${W_DOWNLOADURLS}/NetFx20SP2_x64.exe
        exe="NetFx20SP2_x64.exe"
    fi

    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try_ms_installer "$WINE" "$exe" ${W_OPT_UNATTENDED:+ /q /c:"install.exe /q"}

    if [ "$W_ARCH" = "win32" ]; then
        # We can't stop installing dotnet20sp1 in win2k mode until Wine supports
        # reparse/junction points
        # (see https://bugs.winehq.org/show_bug.cgi?id=10467#c57 )
        # so for now just remove the bogus msvc*80.dll files it installs.
        # See also https://bugs.winehq.org/show_bug.cgi?id=16577
        # This affects Victoria 2 demo, see https://forum.paradoxplaza.com/forum/showthread.php?p=11523967
        rm -f "$W_SYSTEM32_DLLS"/msvc?80.dll
    fi

    w_set_winver 'default'
    w_override_dlls native mscorwks

    W_NGEN_CMD="w_try $WINE $W_DRIVE_C/windows/Microsoft.NET/Framework/v2.0.50727/ngen.exe executequeueditems"
}

verify_dotnet20sp2()
{
    w_dotnet_verify dotnet20sp2
}

#----------------------------------------------------------------

w_metadata dotnet30 dlls \
    title="MS .NET 3.0" \
    publisher="Microsoft" \
    year="2006" \
    media="download" \
    conflicts="dotnet11 dotnet30sp1 dotnet35 dotnet35sp1" \
    file1="dotnetfx3.exe" \
    installed_file1="c:/windows/Microsoft.NET/Framework/v3.0/Microsoft .NET Framework 3.0/logo.bmp"

load_dotnet30()
{
    # I can't find a 64-bit installer anywhere
    w_package_unsupported_win64

    # Originally at https://msdn.microsoft.com/en-us/netframework/bb264589.aspx
    # No longer on microsoft.com, and archive.org is unreliable. Choose amongst the oldest/most reliable looking from
    # http://www.filewatcher.com/m/dotnetfx3.exe.52770576-0.html
    # (and verify sha256sum, of course ;))
    # 2017/04/20: http://descargas.udenar.edu.co/Framework.net/dotnetfx3.exe
    # 2019/08/18: ftp://support.danbit.dk/I/IPP15-C2D/Net%20Framework%203.0/dotnetfx3.exe
    # 2020/04/12: couldn't find a working mirror, so back to archive.org for now:
    w_download ${W_DOWNLOADURLS}/dotnetfx3.exe 6cf8921e00f52bbd888aa7a520a7bac47e818e2a850bcc44494c64d6cbfafdac

    w_call remove_mono

    if test -f /proc/sys/kernel/yama/ptrace_scope; then
        case $(cat /proc/sys/kernel/yama/ptrace_scope) in
            0) ;;
            *) w_warn "If install fails, set /proc/sys/kernel/yama/ptrace_scope to 0.  See https://bugs.winehq.org/show_bug.cgi?id=30410" ;;
        esac
    fi

    case "$W_PLATFORM" in
        windows_cmd)
            osver=$(cmd /c ver)
            case "$osver" in
                *Version?6*) w_die "Vista and up bundle .NET 3.0, so you can't install it like this" ;;
            esac
            ;;
    esac

    # AF's workaround to avoid long pause
    LANGPACKS_BASE_PATH="${W_WINDIR_UNIX}/SYSMSICache/Framework/v3.0"
    test -d "${LANGPACKS_BASE_PATH}" || mkdir -p "${LANGPACKS_BASE_PATH}"
    # shellcheck disable=SC1010
    for lang in ar cs da de el es fi fr he it jp ko nb nl pl pt-BR pt-PT ru sv tr zh-CHS zh-CHT; do
        ln -sf "${W_SYSTEM32_DLLS}/spupdsvc.exe" "${LANGPACKS_BASE_PATH}/dotnetfx3langpack${lang}.exe"
    done

    w_set_winver winxp

    # Delete FontCache 3.0 service, it's in Wine for Mono, breaks native .NET
    # OK if this fails, that just means you have an older Wine.
    "$WINE" sc delete "FontCache3.0.0.0"

    # Not sure when exactly it was fixed, but it works with 4.0+, and doesn't in 3.0
    # Given that 3.x is deprecated, not worth looking into.
    # See https://github.com/Winetricks/winetricks/pull/1271
    # https://bugs.winehq.org/show_bug.cgi?id=47484, et al
    if w_wine_version_in ,4.0 ; then
        WINEDLLOVERRIDES="mscorsvw.exe=b;$WINEDLLOVERRIDES"
        export WINEDLLOVERRIDES
    else
        WINEDLLOVERRIDES="ngen.exe,mscorsvw.exe=b;$WINEDLLOVERRIDES"
        export WINEDLLOVERRIDES
    fi

    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_warn "Installing .NET 3.0 runtime silently, as otherwise it gets hidden behind taskbar. Installation usually takes about 3 minutes."
    w_try "$WINE" "$file1" /q /c:"install.exe /q"

    w_override_dlls native mscorwks

    # Doesn't install any ngen.exe
    # W_NGEN_CMD=""
}

verify_dotnet30()
{
    w_dotnet_verify dotnet30
}

#----------------------------------------------------------------

w_metadata dotnet30sp1 dlls \
    title="MS .NET 3.0 SP1" \
    publisher="Microsoft" \
    year="2007" \
    media="download" \
    conflicts="dotnet11 dotnet20sdk" \
    file1="NetFx30SP1_x86.exe" \
    installed_file1="c:/windows/system32/XpsFilt.dll"    # we're cheating a bit here

load_dotnet30sp1()
{
    # I can't find a 64-bit installer anywhere
    w_package_unsupported_win64

    w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=47436" 4.8 4.15
    w_package_broken "https://bugs.winehq.org/show_bug.cgi?id=48277" 4.16 4.21

    # And a third way, but only with mingw enabled in wine-4.12.1 through wine-4.14
    w_package_broken_mingw  "https://bugs.winehq.org/show_bug.cgi?id=47484" 4.12.1 4.14

    # FIXME: URL?
    w_download ${W_DOWNLOADURLS}/NetFx30SP1_x86.exe 3100df4d4db3965ead9520c887a534115cf6fc7ba100abde45226958b865695b
    # Recipe from https://bugs.winehq.org/show_bug.cgi?id=25060#c10
    w_download ${W_DOWNLOADURLS}/XPSEP%20XP%20and%20Server%202003%2032%20bit.msi 630c86a202c40cbcd430701977d4f1fefa6151624ef9a4870040dff45e547dea "XPSEP XP and Server 2003 32 bit.msi"

    w_call remove_mono
    w_call dotnet30
    #w_wineserver -w
    w_call dotnet20sp1
    #w_wineserver -w

    if w_workaround_wine_bug 47436 "Installing native prntvpt" 4.11, ; then
        w_call prntvpt
    fi

    w_try_cd "$W_CACHE/$W_PACKAGE"

    "$WINE" reg add "HKLM\\Software\\Microsoft\\Net Framework Setup\\NDP\\v3.0" /v Version /t REG_SZ /d "3.0" /f
    "$WINE" reg add "HKLM\\Software\\Microsoft-\\Net Framework Setup\\NDP\\v3.0" /v SP /t REG_DWORD /d 0001 /f

    w_set_winver winxp

    w_try "$WINE" msiexec /i "XPSEP XP and Server 2003 32 bit.msi" ${W_UNATTENDED_SLASH_QB}
    "$WINE" sc delete FontCache3.0.0.0

    w_try_ms_installer "$WINE" "$file1" ${W_OPT_UNATTENDED:+/q}

    w_override_dlls native mscorwks
    w_set_winver 'default'

    # Doesn't install any ngen.exe
    # W_NGEN_CMD=""
}

verify_dotnet30sp1()
{
    w_dotnet_verify dotnet30sp1
}

#----------------------------------------------------------------

w_metadata dotnet35 dlls \
    title="MS .NET 3.5" \
    publisher="Microsoft" \
    year="2007" \
    media="download" \
    conflicts="dotnet11 dotnet20sdk dotnet20sp2 dotnet30" \
    file1="dotnetfx35.exe" \
    installed_file1="c:/windows/Microsoft.NET/Framework/v3.5/MSBuild.exe"

load_dotnet35()
{
    if [ "$W_ARCH" = "win64" ] && w_workaround_wine_bug 45680 "Upgrade to 3.18 for win64 support" ,3.18 ; then
        w_package_unsupported_win64
    fi

    case "$W_PLATFORM" in
        windows_cmd) ;;
        *) w_warn "dotnet35 does not yet fully work or install on wine.  Caveat emptor." ;;
    esac

    w_verify_cabextract_available

    # https://www.microsoft.com/en-us/download/details.aspx?id=21
    w_download ${W_DOWNLOADURLS}/dotnetfx35.exe 3e3a4104bad9a0c270ed5cbe8abb986de9afaf0281a98998bdbdc8eaab85c3b6

    w_call remove_mono

    w_set_winver winxp

    w_override_dlls native mscoree mscorwks
    #w_wineserver -w

    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try_ms_installer "$WINE" "${file1}" /lang:ENU $W_UNATTENDED_SLASH_Q

    # Doesn't install any ngen.exe
    # W_NGEN_CMD=""
}

verify_dotnet35()
{
    w_dotnet_verify dotnet35
}

#----------------------------------------------------------------

w_metadata dotnet35sp1 dlls \
    title="MS .NET 3.5 SP1" \
    publisher="Microsoft" \
    year="2008" \
    media="download" \
    conflicts="dotnet11 dotnet20sp1" \
    file1="dotnetfx35.exe" \
    installed_file1="c:/windows/Microsoft.NET/Framework/v3.5/msbuild.exe.config"

load_dotnet35sp1()
{
    if [ "$W_ARCH" = "win64" ] && w_workaround_wine_bug 46168 "Doesn't install prior to wine-4.0-rc1" ,4.0; then
        w_package_unsupported_win64
    fi

    case "$W_PLATFORM" in
        windows_cmd) ;;
        *) w_warn "dotnet35sp1 does not yet fully work or install on wine.  Caveat emptor." ;;
    esac

    w_verify_cabextract_available

    # https://www.microsoft.com/en-us/download/details.aspx?id=25150
    w_download ${W_DOWNLOADURLS}/dotnetfx35.exe 0582515bde321e072f8673e829e175ed2e7a53e803127c50253af76528e66bc1

    w_call remove_mono

    w_set_winver winxp

    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try_ms_installer "$WINE" dotnetfx35.exe /lang:ENU $W_UNATTENDED_SLASH_Q

    # Doesn't install any ngen.exe
    # W_NGEN_CMD=""
}

verify_dotnet35sp1()
{
    w_dotnet_verify dotnet35sp1
}

#----------------------------------------------------------------

w_metadata dotnet40 dlls \
    title="MS .NET 4.0" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    conflicts="dotnet20sdk" \
    file1="dotNetFx40_Full_x86_x64.exe" \
    installed_file1="c:/windows/Microsoft.NET/Framework/v4.0.30319/ngen.exe"

load_dotnet40()
{
    w_package_warn_win64

    case "$W_PLATFORM" in
        windows_cmd) ;;
        *) w_warn "dotnet40 does not yet fully work or install on wine.  Caveat emptor." ;;
    esac

    if [ "$W_ARCH" = "win64" ]; then
        w_workaround_wine_bug 42701 "On 64-bit, you'll run into https://bugs.winehq.org/show_bug.cgi?id=42701 (missing api-ms-win-core-winrt-roparameterizediid-l1-1-0.dll.RoGetParameterizedTypeInstanceIID", 2.22
    fi

    # https://www.microsoft.com/en-us/download/details.aspx?id=17718
    w_download ${W_DOWNLOADURLS}/dotNetFx40_Full_x86_x64.exe 65e064258f2e418816b304f646ff9e87af101e4c9552ab064bb74d281c38659f

    w_call remove_mono

    w_call winxp

    w_try_cd "$W_CACHE/$W_PACKAGE"

    WINEDLLOVERRIDES=fusion=b w_try_ms_installer "$WINE" dotNetFx40_Full_x86_x64.exe ${W_OPT_UNATTENDED:+/q /c:"install.exe /q"}

    w_override_dlls native mscoree

    "$WINE" reg add "HKLM\\Software\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full" /v Install /t REG_DWORD /d 0001 /f
    "$WINE" reg add "HKLM\\Software\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full" /v Version /t REG_SZ /d "4.0.30319" /f

    W_NGEN_CMD="$WINE $WINEPREFIX/drive_c/windows/Microsoft.NET/Framework/v4.0.30319/ngen.exe executequeueditems"

    w_set_winver 'default'
}

verify_dotnet40()
{
    w_dotnet_verify dotnet40
}

#----------------------------------------------------------------

w_metadata dotnet40_kb2468871 dlls \
    title="MS .NET 4.0 KB2468871" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    conflicts="dotnet20sdk" \
    file1="NDP40-KB2468871-v2-x86.exe"

load_dotnet40_kb2468871()
{
    w_call dotnet40

    # Install KB2468871:
    if [ "$W_ARCH" = "win32" ]; then
        w_download ${W_DOWNLOADURLS}/NDP40-KB2468871-v2-x86.exe 8822672fc864544e0766c80b635973bd9459d719b1af75f51483ff36cfb26f03
        w_try_7z "$W_TMP" "${W_CACHE}/${W_PACKAGE}/NDP40-KB2468871-v2-x86.exe" NDP40-KB2468871.msp
    elif [ "$W_ARCH" = "win64" ]; then
        w_download ${W_DOWNLOADURLS}/NDP40-KB2468871-v2-x64.exe b1b53c3953377b111fe394dd57592d342cfc8a3261a5575253b211c1c2e48ff8
        w_try_7z "$W_TMP" "${W_CACHE}/${W_PACKAGE}/NDP40-KB2468871-v2-x64.exe" NDP40-KB2468871.msp
    fi

    w_try_cd "$W_TMP"
    w_try "$WINE" msiexec /p NDP40-KB2468871.msp

    w_set_winver 'default'
}

verify_dotnet40_kb2468871()
{
    w_dotnet_verify dotnet40
}

#----------------------------------------------------------------

w_metadata dotnet45 dlls \
    title="MS .NET 4.5" \
    publisher="Microsoft" \
    year="2012" \
    media="download" \
    conflicts="dotnet20sdk" \
    file1="dotnetfx45_full_x86_x64.exe" \
    installed_file1="c:/windows/Microsoft.NET/Framework/v4.0.30319/Microsoft.Windows.ApplicationServer.Applications.45.man"

load_dotnet45()
{
    w_package_warn_win64

    w_verify_cabextract_available

    # https://www.microsoft.com/en-us/download/details.aspx?id=17718
    w_download ${W_DOWNLOADURLS}/dotnetfx45_full_x86_x64.exe a04d40e217b97326d46117d961ec4eda455e087b90637cb33dd6cc4a2c228d83

    w_call remove_mono

    # See https://appdb.winehq.org/objectManager.php?sClass=version&iId=25478 for Focht's recipe

    # Seems unneeded in wine-2.0
    # w_call dotnet35
    w_call dotnet40
    w_set_winver win7

    w_try_cd "$W_CACHE/$W_PACKAGE"

    WINEDLLOVERRIDES=fusion=b w_try_ms_installer "$WINE" dotnetfx45_full_x86_x64.exe ${W_OPT_UNATTENDED:+/q /c:"install.exe /q"}

    w_override_dlls native mscoree

    w_warn "Setting Windows version to 2003, otherwise applications using .NET 4.5 will subtly fail"
    w_set_winver win2k3
}

verify_dotnet45()
{
    w_dotnet_verify dotnet45
}

#----------------------------------------------------------------

w_metadata dotnet452 dlls \
    title="MS .NET 4.5.2" \
    publisher="Microsoft" \
    year="2012" \
    media="download" \
    conflicts="dotnet20sdk dotnet46 dotnet462" \
    file1="NDP452-KB2901907-x86-x64-AllOS-ENU.exe" \
    installed_file1="c:/windows/Microsoft.NET/Framework/v4.0.30319/Microsoft.Windows.ApplicationServer.Applications.45.man"

load_dotnet452()
{
    w_package_warn_win64

    w_verify_cabextract_available

    # https://www.microsoft.com/en-us/download/details.aspx?id=17718
    w_download ${W_DOWNLOADURLS}/NDP452-KB2901907-x86-x64-AllOS-ENU.exe 6c2c589132e830a185c5f40f82042bee3022e721a216680bd9b3995ba86f3781

    w_call remove_mono

    # See https://appdb.winehq.org/objectManager.php?sClass=version&iId=25478 for Focht's recipe

    # Seems unneeded in wine-2.0
    # w_call dotnet35
    w_call dotnet40
    w_set_winver win7

    w_try_cd "$W_CACHE/$W_PACKAGE"

    WINEDLLOVERRIDES=fusion=b w_try_ms_installer "$WINE" NDP452-KB2901907-x86-x64-AllOS-ENU.exe ${W_OPT_UNATTENDED:+/q /c:"install.exe /q"}

    w_override_dlls native mscoree

    w_warn "Setting Windows version to 2003, otherwise applications using .NET 4.5 will subtly fail"
    w_set_winver win2k3
}

verify_dotnet452()
{
    w_dotnet_verify dotnet452
}

#----------------------------------------------------------------

w_metadata dotnet46 dlls \
    title="MS .NET 4.6" \
    publisher="Microsoft" \
    year="2015" \
    media="download" \
    file1="NDP46-KB3045557-x86-x64-AllOS-ENU.exe" \
    conflicts="dotnet20sdk" \
    installed_file1="c:/windows/Migration/WTR/netfx45_upgradecleanup.inf"

load_dotnet46()
{
    w_package_warn_win64

    # https://support.microsoft.com/kb/3045560
    w_download ${W_DOWNLOADURLS}/NDP46-KB3045557-x86-x64-AllOS-ENU.exe b21d33135e67e3486b154b11f7961d8e1cfd7a603267fb60febb4a6feab5cf87

    w_call remove_mono

    w_call dotnet45
    w_set_winver win7

    w_try_cd "$W_CACHE/$W_PACKAGE"

    if w_workaround_wine_bug 42470 "$W_PACKAGE may experience heap timeouts" ,3.14; then
        w_warn "If you see heap timeouts like: 'err:ntdll:RtlpWaitForCriticalSection section 0x110060 \"heap.c: main process heap section\" wait timed out in thread 0064, blocked by 0000, retrying (60 sec)', try the patch from https://bugs.winehq.org/show_bug.cgi?id=42470"
    fi

    if w_workaround_wine_bug 38959 "This installer will fail unless run in quiet mode. See: https://bugs.winehq.org/show_bug.cgi?id=38959" ,3.6; then
        WINEDLLOVERRIDES=fusion=b w_try_ms_installer "$WINE" "$file1" /q /c:"install.exe /q"
    else
        WINEDLLOVERRIDES=fusion=b w_try_ms_installer "$WINE" "$file1" ${W_OPT_UNATTENDED:+/q /c:"install.exe /q"}
    fi

    w_override_dlls native mscoree
}

verify_dotnet46()
{
    w_dotnet_verify dotnet46
}

#----------------------------------------------------------------

w_metadata dotnet461 dlls \
    title="MS .NET 4.6.1" \
    publisher="Microsoft" \
    year="2015" \
    media="download" \
    file1="NDP461-KB3102436-x86-x64-AllOS-ENU.exe" \
    conflicts="dotnet20sdk" \
    installed_file1="c:/windows/dotnet461.installed.workaround"

load_dotnet461()
{
    w_package_warn_win64

    # https://www.microsoft.com/en-us/download/details.aspx?id=49982
    w_download ${W_DOWNLOADURLS}/NDP461-KB3102436-x86-x64-AllOS-ENU.exe beaa901e07347d056efe04e8961d5546c7518fab9246892178505a7ba631c301

    w_call remove_mono

    w_call dotnet46
    w_set_winver win7

    w_try_cd "$W_CACHE/$W_PACKAGE"

    WINEDLLOVERRIDES=fusion=b w_try_ms_installer "$WINE" "$file1" /sfxlang:1027 ${W_OPT_UNATTENDED:+/q /norestart}

    w_override_dlls native mscoree

    # Do not rely on temporary files. As a workaround, touch a file instead so that we know it's been installed for list-installed
    w_try touch "${W_WINDIR_UNIX}/dotnet461.installed.workaround"
}

verify_dotnet461()
{
    w_dotnet_verify dotnet461
}

#----------------------------------------------------------------

w_metadata dotnet462 dlls \
    title="MS .NET 4.6.2" \
    publisher="Microsoft" \
    year="2016" \
    media="download" \
    conflicts="dotnet20sdk" \
    installed_file1="c:/windows/dotnet462.installed.workaround"

load_dotnet462()
{
    w_package_warn_win64

    # Official version. See https://www.microsoft.com/en-us/download/details.aspx?id=53344
    w_download ${W_DOWNLOADURLS}/NDP462-KB3151800-x86-x64-AllOS-ENU.exe 28886593e3b32f018241a4c0b745e564526dbb3295cb2635944e3a393f4278d4
    file_package="NDP462-KB3151800-x86-x64-AllOS-ENU.exe"
    unattended_args="/sfxlang:1027 /q /norestart"

    w_call remove_mono

    w_call dotnet461
    w_set_winver win7

    w_try_cd "$W_CACHE/$W_PACKAGE"

    WINEDLLOVERRIDES=fusion=b w_try_ms_installer "$WINE" "$file_package" ${W_OPT_UNATTENDED:+$unattended_args}

    w_override_dlls native mscoree

    # Unfortunately, dotnet462 install the same files that dotnet461 does, but with different checksums
    # The only unique files are temporary ones. As a workaround, touch a file instead so that we know it's been installed for list-installed
    w_try touch "${W_WINDIR_UNIX}/dotnet462.installed.workaround"
}

verify_dotnet462()
{
    w_dotnet_verify dotnet462
}

#----------------------------------------------------------------

w_metadata dotnet471 dlls \
    title="MS .NET 4.7.1" \
    publisher="Microsoft" \
    year="2017" \
    media="download" \
    file1="NDP471-KB4033342-x86-x64-AllOS-ENU.exe" \
    conflicts="dotnet20sdk dotnet30sp1" \
    installed_file1="c:/windows/dotnet471.installed.workaround"

load_dotnet471()
{
    w_package_warn_win64

    # https://www.microsoft.com/en-US/download/details.aspx?id=56116
    w_download ${W_DOWNLOADURLS}/NDP471-KB4033342-x86-x64-AllOS-ENU.exe 63dc850df091f3f137b5d4392f47917f847f8926dc8af1da9bfba6422e495805
    unattended_args="/sfxlang:1027 /q /norestart"

    w_call remove_mono

    w_call dotnet462
    w_set_winver win7

    w_try_cd "$W_CACHE/$W_PACKAGE"

    WINEDLLOVERRIDES=fusion=b w_try_ms_installer "$WINE" "$file1" ${W_OPT_UNATTENDED:+$unattended_args}

    w_override_dlls native mscoree

    # Do not rely on temporary files. As a workaround, touch a file instead so that we know it's been installed for list-installed
    w_try touch "${W_WINDIR_UNIX}/dotnet471.installed.workaround"
}

verify_dotnet471()
{
    w_dotnet_verify dotnet471
}

#----------------------------------------------------------------

w_metadata dotnet472 dlls \
    title="MS .NET 4.7.2" \
    publisher="Microsoft" \
    year="2018" \
    media="download" \
    conflicts="dotnet20sdk" \
    installed_file1="c:/windows/dotnet472.installed.workaround"

load_dotnet472()
{
    w_package_warn_win64

    if w_workaround_wine_bug 42170 "Running un-official repacked .NET 4.7.2 setup until the official version is fixed.", 3.1; then
        # Un-official slim version. See https://repacks.net/forum/viewtopic.php?t=7
        file_package="dotNetFx472_Full_x86_x64_Slim.exe"
        w_download "${W_DOWNLOADURLS}/dotNetFx472_Slim_x86_x64.exe" a36da041b8f46079f8e16647312d642953cde520f4a600ad5b3f4f90a23495a7 $file_package
        unattended_args="/ai /gm2"
    else
        # Official version. See https://www.microsoft.com/en-us/download/details.aspx?id=53344
        w_download ${W_DOWNLOADURLS}/NDP472-KB4054530-x86-x64-AllOS-ENU.exe c908f0a5bea4be282e35acba307d0061b71b8b66ca9894943d3cbb53cad019bc
        file_package="NDP472-KB4054530-x86-x64-AllOS-ENU.exe"
        unattended_args="/sfxlang:1027 /q /norestart"
    fi

    w_call remove_mono

    w_call dotnet462
    w_set_winver win7

    w_try_cd "$W_CACHE/$W_PACKAGE"

    WINEDLLOVERRIDES=fusion=b w_try_ms_installer "$WINE" "$file_package" ${W_OPT_UNATTENDED:+$unattended_args}

    w_override_dlls native mscoree

    # Do not rely on temporary files. As a workaround, touch a file instead so that we know it's been installed for list-installed
    w_try touch "${W_WINDIR_UNIX}/dotnet472.installed.workaround"
}

verify_dotnet472()
{
    w_dotnet_verify dotnet472
}

#----------------------------------------------------------------

w_metadata dotnet48 dlls \
    title="MS .NET 4.8" \
    publisher="Microsoft" \
    year="2019" \
    media="download" \
    file1="ndp48-x86-x64-allos-enu.exe" \
    conflicts="dotnet20sdk" \
    installed_file1="c:/windows/dotnet48.installed.workaround"

load_dotnet48()
{
    w_package_warn_win64

    # Official version. See https://dotnet.microsoft.com/download/dotnet-framework/net48
    w_download ${W_DOWNLOADURLS}/ndp48-x86-x64-allos-enu.exe 95889d6de3f2070c07790ad6cf2000d33d9a1bdfc6a381725ab82ab1c314fd53
    unattended_args="/sfxlang:1027 /q /norestart"

    w_call remove_mono

    w_call dotnet40
    w_set_winver win7

    w_try_cd "$W_CACHE/$W_PACKAGE"

    WINEDLLOVERRIDES=fusion=b w_try_ms_installer "$WINE" "$file1" ${W_OPT_UNATTENDED:+$unattended_args}

    w_override_dlls native mscoree

    # Do not rely on temporary files. As a workaround, touch a file instead so that we know it's been installed for list-installed
    w_try touch "${W_WINDIR_UNIX}/dotnet48.installed.workaround"
}

verify_dotnet48()
{
    w_dotnet_verify dotnet48
}

#----------------------------------------------------------------

w_metadata dotnet_verifier dlls \
    title="MS .NET Verifier" \
    publisher="Microsoft" \
    year="2016" \
    media="download" \
    file1="netfx_setupverifier_new.zip" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/netfx_setupverifier.exe"

load_dotnet_verifier()
{
    # https://blogs.msdn.microsoft.com/astebner/2008/10/13/net-framework-setup-verification-tool-users-guide/
    # 2016/10/26: sha256sum 1daf4b1b27669b65f613e17814da3c8342d3bfa9520a65a880c58d6a2a6e32b5, adds .NET Framework 4.6.{1,2} support
    # 2017/06/12: sha256sum 310a0341fbe68f5b8601f2d8deef5d05ca6bce50df03912df391bc843794ef60, adds .NET Framework 4.7 support
    # 2018/06/03: sha256sum 13fd683fd604f9de09a9e649df303100b81e6797f868024d55e5c2f3c14aa9a6, adds .NET Framework 4.7.{1,2} support

    w_download ${W_DOWNLOADURLS}/netfx_setupverifier_new.zip 13fd683fd604f9de09a9e649df303100b81e6797f868024d55e5c2f3c14aa9a6

    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try_unzip "$W_SYSTEM32_DLLS" netfx_setupverifier_new.zip netfx_setupverifier.exe

    w_warn "You can run the .NET Verifier with \"${WINE} netfx_setupverifier.exe\""
}

#----------------------------------------------------------------

w_metadata dx8vb dlls \
    title="MS dx8vb.dll from DirectX 8.1 runtime" \
    publisher="Microsoft" \
    year="2001" \
    media="download" \
    file1="DX81NTger.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/dx8vb.dll"

load_dx8vb()
{
    # https://www.microsoft.com/de-de/download/details.aspx?id=10968
    w_download ${W_DOWNLOADURLS}/DX81NTger.exe 31513966a29dc100165072891d21b5c5e0dd2632abf3409a843cefb3a9886f13

    w_try_cabextract -d "$W_SYSTEM32_DLLS" -F dx8vb.dll "$W_CACHE/$W_PACKAGE"/DX81NTger.exe

    w_override_dlls native dx8vb
}

#----------------------------------------------------------------

w_metadata dxdiagn dlls \
    title="DirectX Diagnostic Library" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    conflicts="dxdiagn_feb2010" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/dxdiagn.dll"

load_dxdiagn()
{
    helper_win7sp1 x86_microsoft-windows-d..x-directxdiagnostic_31bf3856ad364e35_6.1.7601.17514_none_25cb021dbc0611db/dxdiagn.dll
    w_try cp "$W_TMP/x86_microsoft-windows-d..x-directxdiagnostic_31bf3856ad364e35_6.1.7601.17514_none_25cb021dbc0611db/dxdiagn.dll" "$W_SYSTEM32_DLLS/dxdiagn.dll"
    w_override_dlls native,builtin dxdiagn
    w_try_regsvr dxdiagn.dll

    if [ "$W_ARCH" = "win64" ]; then
        helper_win7sp1_x64 amd64_microsoft-windows-d..x-directxdiagnostic_31bf3856ad364e35_6.1.7601.17514_none_81e99da174638311/dxdiagn.dll
        w_try cp "$W_TMP/amd64_microsoft-windows-d..x-directxdiagnostic_31bf3856ad364e35_6.1.7601.17514_none_81e99da174638311/dxdiagn.dll" "$W_SYSTEM64_DLLS/dxdiagn.dll"
        w_try_regsvr64 dxdiagn.dll
    fi
}

#----------------------------------------------------------------

w_metadata dxdiagn_feb2010 dlls \
    title="DirectX Diagnostic Library (February 2010)" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    conflicts="dxdiagn" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/dxdiagn.dll"

load_dxdiagn_feb2010()
{
    helper_directx_dl

    w_try_cabextract -d "$W_TMP" -L -F dxnt.cab "$W_CACHE"/directx9/$DIRECTX_NAME
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dxdiagn.dll' "$W_TMP/dxnt.cab"
    w_override_dlls native dxdiagn
    w_try_regsvr dxdiagn.dll
}

#----------------------------------------------------------------

w_metadata dsound dlls \
    title="MS DirectSound from DirectX user redistributable" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/dsound.dll"

load_dsound()
{
    helper_directx_dl

    w_try_cabextract -d "$W_TMP" -L -F dxnt.cab "$W_CACHE"/directx9/$DIRECTX_NAME
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'dsound.dll' "$W_TMP/dxnt.cab"

    # Don't try to register native dsound; it doesn't export DllRegisterServer().
    w_try_regsvr dsound.dll
    w_override_dlls native dsound
}

#----------------------------------------------------------------

w_metadata esent dlls \
    title="MS Extensible Storage Engine" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/esent.dll"

load_esent()
{
    helper_win7sp1 x86_microsoft-windows-e..estorageengine-isam_31bf3856ad364e35_6.1.7601.17514_none_f3ebb0cc8a4dd814/esent.dll
    w_try cp "$W_TMP/x86_microsoft-windows-e..estorageengine-isam_31bf3856ad364e35_6.1.7601.17514_none_f3ebb0cc8a4dd814/esent.dll" "$W_SYSTEM32_DLLS/esent.dll"

    if [ "$W_ARCH" = "win64" ]; then
        helper_win7sp1_x64 amd64_microsoft-windows-e..estorageengine-isam_31bf3856ad364e35_6.1.7601.17514_none_500a4c5042ab494a/esent.dll
        w_try cp "$W_TMP/amd64_microsoft-windows-e..estorageengine-isam_31bf3856ad364e35_6.1.7601.17514_none_500a4c5042ab494a/esent.dll" "$W_SYSTEM64_DLLS/esent.dll"
    fi

    w_override_dlls native,builtin esent
}

#----------------------------------------------------------------

# $1 - faudio archive name (required)
helper_faudio()
{
    faudio_archive="$1"
    faudio_version="$(basename "${faudio_archive}" .tar.xz)"

    w_try_cd "$W_TMP"
    w_try tar -Jxf "${W_CACHE}/${W_PACKAGE}/${faudio_archive}"

    if [ -d "${faudio_version}/x32" ]; then
        w_info "Installing 32-bit binaries since present; upstreams says they may be broken"

        # They ship an installation script, but it's bash (and we have all needed functionality already)
        # Unless they add something more complex, this should suffice:
        for dll in "${faudio_version}/x32/"*.dll; do
            shortdll="$(basename "${dll}" .dll)"
            w_try cp "${dll}" "$W_SYSTEM32_DLLS"
            w_override_dlls native "$shortdll"
        done
    fi

    if [ "$W_ARCH" = "win64" ]; then
        for dll in "${faudio_version}/x64/"*.dll; do
            # Note: 'libgcc_s_sjlj-1.dll' is not included in the 64-bit build
            shortdll="$(basename "${dll}" .dll)"
            w_try cp "${dll}" "$W_SYSTEM64_DLLS"
            w_override_dlls native "$shortdll"
        done
    fi
}


#----------------------------------------------------------------

w_metadata faudio1906 dlls \
    title="FAudio (xaudio reimplementation, with xna support) builds for win32 (19.06)" \
    publisher="Kron4ek" \
    year="2019" \
    media="download" \
    file1="faudio-19.06.tar.xz" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/FAudio.dll"

load_faudio1906()
{
    w_download ${W_DOWNLOADURLS}/faudio-19.06.tar.xz 87639e30f9e913685829e05b925809598409e54c4c51e3d74b977cedd658aaf3
    helper_faudio "$file1"
}

#----------------------------------------------------------------

w_metadata faudio190607 dlls \
    title="FAudio (xaudio reimplementation, with xna support) builds for win32 (19.06.07)" \
    publisher="Kron4ek" \
    year="2019" \
    media="download" \
    file1="faudio-19.06.07.tar.xz" \
    installed_file1="$W_SYSTEM64_DLLS_WIN64/FAudio.dll"

load_faudio190607()
{
    # Starting in 19.06.07; before that ships them, but they're supposedly broken
    w_package_unsupported_win32

    w_download ${W_DOWNLOADURLS}/faudio-19.06.07.tar.xz e17e3a9dadeb1017dc369fe0d46c3d1945ebceadb7ad2f94a3a1448435ab3f6c
    helper_faudio "$file1"
}
#----------------------------------------------------------------

w_metadata faudio dlls \
    title="FAudio (xaudio reimplementation, with xna support) builds for win32 (latest)" \
    publisher="Kron4ek" \
    year="2019" \
    media="download" \
    installed_file1="$W_SYSTEM64_DLLS_WIN64/FAudio.dll"

load_faudio()
{
    # Starting in 19.06.07; before that ships them, but they're supposedly broken
    w_package_unsupported_win32

    w_download_to "${W_TMP_EARLY}" "https://raw.githubusercontent.com/Kron4ek/FAudio-Builds/master/LATEST"
    faudio_version="$(cat "${W_TMP_EARLY}/LATEST")"
    w_linkcheck_ignore=1 w_download "https://github.com/Kron4ek/FAudio-Builds/releases/download/${faudio_version}/faudio-${faudio_version}.tar.xz"
    helper_faudio "faudio-${faudio_version}.tar.xz"
}

#----------------------------------------------------------------

w_metadata filever dlls \
    title="Microsoft's filever, for dumping file version info" \
    publisher="Microsoft" \
    year="20??" \
    media="download" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/filever.exe"

load_filever()
{
    helper_winxpsp2_support_tools filever.exe
    w_try cp "$W_TMP/filever.exe" "$W_SYSTEM32_DLLS/filever.exe"
}

#----------------------------------------------------------------

# FIXME: update winetricks_is_installed to look at installed_file2..n
# https://github.com/Winetricks/winetricks/issues/988
w_metadata flash dlls \
    title="Flash Player 29" \
    publisher="Adobe" \
    year="2018" \
    media="download" \
    file1="fp_29.0.0.171_archive.zip" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/Macromed/Flash/FlashUtil32_29_0_0_171_Plugin.exe" \
    installed_file2="$W_SYSTEM32_DLLS_WIN/Macromed/Flash/FlashUtil32_29_0_0_171_ActiveX.exe" \
    installed_file3="$W_SYSTEM32_DLLS_WIN/Macromed/Flash/flashplayer29_0r0_171_win_sa.exe" \
    homepage="https://www.adobe.com/products/flashplayer/"

load_flash()
{
    _W_ver_major=29
    _W_ver_minor=0
    _W_ver_rel=0
    _W_ver_build=171
    _W_dirname="${_W_ver_major}_${_W_ver_minor}_r${_W_ver_rel}_${_W_ver_build}"
    _W_archive="fp_${_W_ver_major}.${_W_ver_minor}.${_W_ver_rel}.${_W_ver_build}_archive.zip"
    _W_fileprefix="flashplayer${_W_ver_major}_${_W_ver_minor}r${_W_ver_rel}_${_W_ver_build}"

    # 2013/07/09: Adobe Flash 10 is no longer supported.
    # 2013/06/24: Adobe Flash 10.3 won't even install for me, it tells you to go get a newer version!
    # See
    # https://blogs.adobe.com/psirt/
    # https://get.adobe.com/de/flashplayer/otherversions/
    # Now, we install older versions by using zipfiles at
    # https://helpx.adobe.com/flash-player/kb/archived-flash-player-versions.html

    # 2018/06/24: d4b6f9a5e42cc9f2c7cbd1fd72059d4c1bead91b076afa2ca042d28f0fd7bedb
    w_linkcheck_ignore=1 w_download "https://fpdownload.macromedia.com/pub/flashplayer/installers/archive/$_W_archive" d4b6f9a5e42cc9f2c7cbd1fd72059d4c1bead91b076afa2ca042d28f0fd7bedb

    # If OS version is Vista or newer:
    #   1. NPAPI plugin doesn't work
    #   2. In win64 prefix, "File not found." dialog appears when installing:
    #      'wine: cannot find L"C:\\windows\\system32\\Macromed\\Temp\\{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}\\InstallFlashPlayer.exe"'
    w_set_winver winxp

    # ActiveX plugin
    # 2014/10/02: 3958827058648cfe05fc6ee510685e8d93f995d3428c3eedbd6814704765672a
    w_try_unzip "$W_TMP" "$W_CACHE/flash/$_W_archive" "$_W_dirname/${_W_fileprefix}_winax.exe"
    w_try_cd "$W_TMP/$_W_dirname"
    w_try "$WINE" "${_W_fileprefix}_winax.exe" ${W_OPT_UNATTENDED:+ /install}

    # Mozilla / Firefox (NPAPI) plugin
    # 2014/10/02: 17496fd3c863c180aead953d7d4499dd36f997a9570abc2b92f55e4ea1d55d73
    w_try_unzip "$W_TMP" "$W_CACHE/flash/$_W_archive" "$_W_dirname/${_W_fileprefix}_win.exe"
    w_try "$WINE" "${_W_fileprefix}_win.exe" ${W_OPT_UNATTENDED:+ /install}

    # Projector (standalone player)
    # 2015/07/06: 8640c42e73dc44125045e17abd32412c48f3808a8393c94fc8281cf4b0d87bdc
    w_try_unzip "$W_TMP" "$W_CACHE/flash/$_W_archive" "$_W_dirname/${_W_fileprefix}_win_sa.exe"
    w_try mv "${_W_fileprefix}_win_sa.exe" "$W_SYSTEM32_DLLS/Macromed/Flash"

    # After updating the above, you should carry the following steps out by
    # hand to verify that plugin works.

    #    rm -rf ~/.cache/winetricks/flash
    #    w_try_cd ~/winetricks/src
    #    rm -rf ~/.wine
    #    sh winetricks -q flash ie7
    #    cd "~/.wine/drive_c/Program Files/Internet Explorer"
    #    wine iexplore.exe https://www.adobe.com/software/flash/about
    # Verify that the version of Flash shows up and that you're not prompted
    # to install Flash again
    #
    #    w_try_cd ~/winetricks/src
    #    rm -rf ~/.wine
    #    sh winetricks -q flash firefox
    #    cd "~/.wine/drive_c/Program Files/Mozilla Firefox"
    #    wine firefox.exe https://www.adobe.com/software/flash/about
    # Verify that the version of Flash shows up and that you're not prompted
    # to install Flash again

    unset _W_ver_major _W_ver_minor _W_ver_rel _W_ver_build _W_dirname _W_archive _W_fileprefix
}

#----------------------------------------------------------------

# $1 - gallium nine standalone archive name (required)
helper_galliumnine()
{
    _W_galliumnine_archive="${1}"
    _W_galliumnine_tmp="$W_TMP/galliumnine"

    w_try rm -rf "$_W_galliumnine_tmp"
    w_try mkdir -p "$_W_galliumnine_tmp"
    w_try tar -C "$_W_galliumnine_tmp" --strip-components=1 -zxf "$W_CACHE/$W_PACKAGE/$_W_galliumnine_archive"
    w_try mv "$_W_galliumnine_tmp/lib32/d3d9-nine.dll.so" "$W_SYSTEM32_DLLS/d3d9-nine.dll"
    w_try mv "$_W_galliumnine_tmp/bin32/ninewinecfg.exe.so" "$W_SYSTEM32_DLLS/ninewinecfg.exe"
    if test "$W_ARCH" = "win64"; then
        w_try mv "$_W_galliumnine_tmp/lib64/d3d9-nine.dll.so" "$W_SYSTEM64_DLLS/d3d9-nine.dll"
        w_try mv "$_W_galliumnine_tmp/bin64/ninewinecfg.exe.so" "$W_SYSTEM64_DLLS/ninewinecfg.exe"
    fi
    w_try rm -rf "$_W_galliumnine_tmp"
    # use ninewinecfg to enable gallium nine
    WINEDEBUG=-all w_try "$WINE_MULTI" ninewinecfg -e

    unset _W_galliumnine_tmp _W_galliumnine_archive
}

w_metadata galliumnine05 dlls \
    title="Gallium Nine Standalone (v0.5)" \
    publisher="Gallium Nine Team" \
    year="2019" \
    media="download" \
    file1="gallium-nine-standalone-v0.5.tar.gz" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3d9-nine.dll" \
    installed_file2="$W_SYSTEM32_DLLS_WIN/ninewinecfg.exe" \
    homepage="https://github.com/iXit/wine-nine-standalone"

load_galliumnine05()
{
    w_download "${W_DOWNLOADURLS}/gallium-nine-standalone-v0.5.tar.gz" c46e06b13a3ba0adee75b27a8b54e9d772f83ed29dee5e203364460771fb1bcd
    helper_galliumnine "$file1"
}

w_metadata galliumnine dlls \
    title="Gallium Nine Standalone (latest)" \
    publisher="Gallium Nine Team" \
    year="2019" \
    media="download" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/d3d9-nine.dll" \
    installed_file2="$W_SYSTEM32_DLLS_WIN/ninewinecfg.exe" \
    homepage="https://github.com/iXit/wine-nine-standalone"

load_galliumnine()
{
    _W_galliumnine_version="$(w_get_github_latest_release iXit wine-nine-standalone)"
    w_linkcheck_ignore=1 w_download "https://github.com/iXit/wine-nine-standalone/releases/download/${_W_galliumnine_version}/gallium-nine-standalone-${_W_galliumnine_version}.tar.gz"
    helper_galliumnine "gallium-nine-standalone-${_W_galliumnine_version}.tar.gz"
    unset _W_galliumnine_version
}

#----------------------------------------------------------------

w_metadata gdiplus dlls \
    title="MS GDI+" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/gdiplus.dll"

load_gdiplus()
{
    # gdiplus has changed in win7. See https://bugs.winehq.org/show_bug.cgi?id=32163#c3
    helper_win7sp1 x86_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.7601.17514_none_72d18a4386696c80/gdiplus.dll
    w_try cp "$W_TMP/x86_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.7601.17514_none_72d18a4386696c80/gdiplus.dll" "$W_SYSTEM32_DLLS/gdiplus.dll"

    if [ "$W_ARCH" = "win64" ]; then
        helper_win7sp1_x64 amd64_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.7601.17514_none_2b24536c71ed437a/gdiplus.dll
        w_try cp "$W_TMP/amd64_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.7601.17514_none_2b24536c71ed437a/gdiplus.dll" "$W_SYSTEM64_DLLS/gdiplus.dll"
    fi

    # For some reason, native, builtin isn't good enough...?
    w_override_dlls native gdiplus
}

#----------------------------------------------------------------

w_metadata gdiplus_winxp dlls \
    title="MS GDI+" \
    publisher="Microsoft" \
    year="2009" \
    media="manual_download" \
    file1="WindowsXP-KB975337-x86-ENU.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/gdiplus.dll"

load_gdiplus_winxp()
{
    # https://www.microsoft.com/en-us/download/details.aspx?id=5339
    w_download ${W_DOWNLOADURLS}/WindowsXP-KB975337-x86-ENU.exe 699e76e9f100db3d50da8762c484a369df4698d4b84f7821d4df0e37ce68bcbe
    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try_cabextract -d "$W_TMP" -F _sfx_0005._p "$W_CACHE/${W_PACKAGE}/$file1"
    w_try cp "$W_TMP/_sfx_0005._p" "$W_SYSTEM32_DLLS/gdiplus.dll"

    # For some reason, native, builtin isn't good enough...?
    w_override_dlls native gdiplus
}

#----------------------------------------------------------------

w_metadata glidewrapper dlls \
    title="GlideWrapper" \
    publisher="Rolf Neuberger" \
    year="2005" \
    media="download" \
    file1="GlideWrapper084c.exe" \
    installed_file1="c:/windows/glide3x.dll"

load_glidewrapper()
{
    w_download ${W_DOWNLOADURLS}/GlideWrapper084c.exe 3c4185bd7eac9bd50e0727a7b5165ec8273230455480cf94358e1bbd35921b69
    w_try_cd "$W_CACHE/$W_PACKAGE"

    # The installer opens its README in a web browser, really annoying when doing make check/test:
    # FIXME: maybe we should back up this key first?
    if test ${W_OPT_UNATTENDED}; then
        cat > "$W_TMP"/disable-browser.reg <<_EOF_
REGEDIT4

[HKEY_CURRENT_USER\\Software\\Wine\\WineBrowser]
"Browsers"=""

_EOF_
        w_try_regedit "$W_TMP_WIN"\\disable-browser.reg

    fi

    # NSIS installer
    w_try "$WINE" "$file1" ${W_OPT_UNATTENDED:+ /S}

    if test ${W_OPT_UNATTENDED}; then
        "$WINE" reg delete "HKEY_CURRENT_USER\\Software\\Wine\\WineBrowser" /v Browsers /f || true
    fi
}

#----------------------------------------------------------------

w_metadata gfw dlls \
    title="MS Games For Windows Live (xlive.dll)" \
    publisher="Microsoft" \
    year="2008" \
    media="download" \
    file1="gfwlivesetupmin.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/xlive.dll"

load_gfw()
{
    # https://www.microsoft.com/games/en-us/live/pages/livejoin.aspx
    # http://www.next-gen.biz/features/should-games-for-windows-live-die
    w_download ${W_DOWNLOADURLS}/gfwlivesetupmin.exe b14609508e2f8dba0886ded84e2817ad532ebfa31f8a6d4be2e6a5a03a9d7c23

    # FIXME: Depends on .NET 20, but is it really needed? For now, skip it.
    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try "$WINE" gfwlivesetupmin.exe /nodotnet $W_UNATTENDED_SLASH_Q

    w_call msasn1
}

#----------------------------------------------------------------

w_metadata glut dlls \
    title="The glut utility library for OpenGL" \
    publisher="Mark J. Kilgard" \
    year="2001" \
    media="download" \
    file1="glut-3.7.6-bin.zip" \
    installed_file1="c:/glut-3.7.6-bin/glut32.lib"

load_glut()
{
    w_download ${W_DOWNLOADURLS}/glut-3.7.6-bin.zip 788e97653bfd527afbdc69e1b7c6bcf9cb45f33d13ddf9d676dc070da92f80d4
    # FreeBSD unzip rm -rf's inside the target directory before extracting:
    w_try_unzip "$W_TMP" "$W_CACHE"/glut/glut-3.7.6-bin.zip
    w_try mv "$W_TMP/glut-3.7.6-bin" "$W_DRIVE_C"
    w_try cp "$W_DRIVE_C"/glut-3.7.6-bin/glut32.dll "$W_SYSTEM32_DLLS"
    w_warn "If you want to compile glut programs, add c:/glut-3.7.6-bin to LIB and INCLUDE"
}

#----------------------------------------------------------------

w_metadata gmdls dlls \
    title="General MIDI DLS Collection" \
    publisher="Microsoft / Roland" \
    year="1999" \
    media="download" \
    file1="../directx9/directx_apr2006_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/drivers/gm.dls"

load_gmdls()
{
    w_download_to directx9 ${W_DOWNLOADURLS}/directx_apr2006_redist.exe dd8c3d401efe4561b67bd88475201b2f62f43cd23e4acc947bb34a659fa74952

    w_try_cabextract -d "$W_TMP" -F DirectX.cab "$W_CACHE"/directx9/directx_apr2006_redist.exe
    w_try_cabextract -d "$W_TMP" -F gm16.dls "$W_TMP"/DirectX.cab
    w_try mv "$W_TMP"/gm16.dls "$W_SYSTEM32_DLLS"/drivers/gm.dls
    if test "$W_ARCH" = "win64"; then
        w_try_cd "$W_SYSTEM64_DLLS"/drivers
        w_try ln -s ../../syswow64/drivers/gm.dls
    fi
}

#----------------------------------------------------------------
# um, codecs are kind of clustered here.  They probably deserve their own real category.

w_metadata allcodecs dlls \
    title="All codecs (dirac, ffdshow, icodecs, cinepak, l3codecx, xvid) except wmp" \
    publisher="various" \
    year="1995-2009" \
    media="download"

load_allcodecs()
{
    w_call dirac
    w_call l3codecx
    w_call ffdshow
    w_call icodecs
    w_call cinepak
    w_call xvid
}

#----------------------------------------------------------------

w_metadata dirac dlls \
    title="The Dirac directshow filter v1.0.2" \
    publisher="Dirac" \
    year="2009" \
    media="download" \
    file1="DiracDirectShowFilter-1.0.2.exe" \
    installed_file1="$W_PROGRAMS_X86_WIN/Dirac/DiracDecoder.dll"

load_dirac()
{
    w_download ${W_DOWNLOADURLS}/DiracDirectShowFilter-1.0.2.exe 7257de4be940405637bb5d11c1179f7db86f165f21fc0ba24f42a9ecbc55fe20

    # Avoid mfc90 not found error.  (DiracSplitter-libschroedinger.ax needs mfc90 to register itself, I think.)
    w_call vcrun2008

    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_ahk_do "
        SetTitleMatchMode, 2
        run DiracDirectShowFilter-1.0.2.exe
        WinWait, Dirac, Welcome
        if ( w_opt_unattended > 0 ) {
            ControlClick, Button2
            WinWait, Dirac, License
            Sleep 1000
            ControlClick, Button2
            WinWait, Dirac, Location
            Sleep 1000
            ControlClick, Button2
            WinWait, Dirac, Components
            Sleep 1000
            ControlClick, Button2
            WinWait, Dirac, environment
            Sleep 1000
            ControlCLick, Button1
            WinWait, Dirac, installed
            Sleep 1000
            ControlClick, Button2
        }
        WinWaitClose
    "
}

#----------------------------------------------------------------

w_metadata ffdshow dlls \
    title="ffdshow video codecs" \
    publisher="doom9 folks" \
    year="2010" \
    media="download" \
    file1="ffdshow_beta7_rev3154_20091209.exe" \
    installed_file1="$W_PROGRAMS_X86_WIN/ffdshow/ff_liba52.dll" \
    homepage="https://ffdshow-tryout.sourceforge.io/"

load_ffdshow()
{
    w_download ${W_DOWNLOADURLS}/ffdshow_beta7_rev3154_20091209.exe 86fb22e9a79a1c83340a99fd5722974a4d03948109d404a383c4334fab8f8860
    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try "$WINE" ffdshow_beta7_rev3154_20091209.exe $W_UNATTENDED_SLASH_SILENT
}

#----------------------------------------------------------------

w_metadata hid dlls \
    title="MS hid" \
    publisher="Microsoft" \
    year="2003" \
    media="download" \
    file1="../win2ksp4/W2KSP4_EN.EXE" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/hid.dll"

load_hid()
{
    helper_win2ksp4 i386/hid.dl_
    w_try_cabextract --directory="$W_SYSTEM32_DLLS" "$W_TMP"/i386/hid.dl_

    w_override_dlls native hid
}

#----------------------------------------------------------------

w_metadata icodecs dlls \
    title="Indeo codecs" \
    publisher="Intel" \
    year="1998" \
    media="download" \
    file1="codinstl.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/ir50_32.dll"

load_icodecs()
{
    # Note: this codec is insecure, see
    # https://support.microsoft.com/kb/954157
    # Original source, ftp://download.intel.com/support/createshare/camerapack/codinstl.exe, had same checksum
    # 2010/11/14: http://codec.alshow.co.kr/Down/codinstl.exe
    # 2014/04/11: http://www.cucusoft.com/codecdownload/codinstl.exe (linked from http://www.cucusoft.com/codec.asp)
    w_download "${W_DOWNLOADURLS}/codinstl.exe" 0979d43568111cadf0b3bf43cd8d746ac3de505759c14f381592b4f8439f6c95

    # Extract the installer so that we can use the included Install Shield
    # response file for unattended installations
    w_try_cabextract -d "$W_TMP/codinstl/" "$W_CACHE/$W_PACKAGE/codinstl.exe"
    w_try_cd "$W_TMP/codinstl/"
    w_try "$WINE" "setup.exe" ${W_OPT_UNATTENDED:+/s}

    # Work around bug in codec's installer?
    # https://support.britannica.com/other/touchthesky/win/issues/TSTUw_150.htm
    # https://appdb.winehq.org/objectManager.php?sClass=version&iId=7091
    w_try_regsvr ir50_32.dll

    # Apparently some codecs are missing, see https://github.com/Winetricks/winetricks/issues/302
    # Download at https://www.moviecodec.com/download-codec-packs/indeo-codecs-legacy-package-31/
    w_download ${W_DOWNLOADURLS}/iv5setup.exe 51bec25488b5b94eb3ce49b0a117618c9526161fd0753817a7a724ce25ff0cad

    # Extract the installer so that we can create and use a pre-recorded
    # Install Shield response file for unattended installations
    w_try_cabextract -d "$W_TMP/iv5setup/" "$W_CACHE/$W_PACKAGE/iv5setup.exe"

    # Create the response file with the following excluded components
    # - IV5 Directshow plugin (gives error about missing Ivfsrc.ax)
    # - Web browser (Netscape) plugin
    # http://www.silentinstall.org/InstallShield
    cat > "$W_TMP/iv5setup/setup.iss" <<_EOF_
[InstallShield Silent]
Version=v5.00.000
File=Response File
[File Transfer]
OverwriteReadOnly=NoToAll
[DlgOrder]
Dlg0=SdWelcome-0
Count=8
Dlg1=SdLicense-0
Dlg2=SdAskDestPath-0
Dlg3=SdSetupTypeEx-0
Dlg4=SdComponentDialog2-0
Dlg5=AskYesNo-0
Dlg6=SdStartCopy-0
Dlg7=SdFinish-0
[SdWelcome-0]
Result=1
[SdLicense-0]
Result=1
[SdAskDestPath-0]
szDir=C:\Program Files\Ligos\Indeo
Result=1
[SdSetupTypeEx-0]
Result=Custom
[SdComponentDialog2-0]
Indeo Audio Codec-type=string
Indeo Audio Codec-count=1
Indeo Audio Codec-0=Indeo Audio Codec\Indeo Audio Encoder
Component-type=string
Component-count=12
Component-0=Indeo Video 5 Quick Compressors
Component-1=Indeo® Video 5 Codec
Component-2=Indeo Video 4 Codec
Component-3=Indeo Video 3.2 Codec
Component-4=Indeo Audio Codec
Component-5=Indeo Video Raw (YVU9) Codec
Component-6=Indeo Video 4 Quick Compressors
Component-7=Indeo Video 5 Compressor Help Files
Component-8=Indeo Video 4 Compressor Help Files
Component-9=Indeo Software Release Notes
Component-10=Indeo Software Installation Source Code
Component-11=Indeo Software Uninstallation
Result=1
[AskYesNo-0]
Result=0
[SdStartCopy-0]
Result=1
[Application]
Name=Indeo® Software
Version=1.00.000
Company=Ligos
Lang=0009
[SdFinish-0]
Result=1
bOpt1=0
bOpt2=0
_EOF_

    w_try_cd "$W_TMP/iv5setup/"
    w_try "$WINE" "setup.exe" ${W_OPT_UNATTENDED:+/s}

    # Note, this leaves a dangling explorer window.
    # Wait for it to appear and kill it
    while ! inode_pid=$(pgrep -f "explorer.exe.*Indeo"); do
        sleep 1
    done
    kill -HUP "$inode_pid"
}

#----------------------------------------------------------------

w_metadata iertutil dlls \
    title="MS Runtime Utility" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/iertutil.dll"

load_iertutil()
{
    helper_win7sp1 x86_microsoft-windows-ie-runtimeutilities_31bf3856ad364e35_8.0.7601.17514_none_64655b7c61c841cb/iertutil.dll
    w_try cp "$W_TMP/x86_microsoft-windows-ie-runtimeutilities_31bf3856ad364e35_8.0.7601.17514_none_64655b7c61c841cb/iertutil.dll" "$W_SYSTEM32_DLLS/iertutil.dll"

    if [ "$W_ARCH" = "win64" ]; then
        helper_win7sp1_x64 amd64_microsoft-windows-ie-runtimeutilities_31bf3856ad364e35_8.0.7601.17514_none_c083f7001a25b301/iertutil.dll
        w_try cp "$W_TMP/amd64_microsoft-windows-ie-runtimeutilities_31bf3856ad364e35_8.0.7601.17514_none_c083f7001a25b301/iertutil.dll" "$W_SYSTEM64_DLLS/iertutil.dll"
    fi

    w_override_dlls native,builtin iertutil
}

#----------------------------------------------------------------

w_metadata itircl dlls \
    title="MS itircl.dll" \
    publisher="Microsoft" \
    year="1999" \
    media="download" \
    file1="../hhw/htmlhelp.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/itircl.dll"

load_itircl()
{
    # https://msdn.microsoft.com/en-us/library/windows/desktop/ms669985(v=vs.85).aspx
    w_download_to hhw ${W_DOWNLOADURLS}/htmlhelp.exe b2b3140d42a818870c1ab13c1c7b8d4536f22bd994fa90aade89729a6009a3ae

    w_try_cabextract -d "$W_TMP" -F hhupd.exe "$W_CACHE"/hhw/htmlhelp.exe
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -F itircl.dll "$W_TMP"/hhupd.exe
    w_override_dlls native itircl
    w_try_regsvr itircl.dll
}

#----------------------------------------------------------------

w_metadata itss dlls \
    title="MS itss.dll" \
    publisher="Microsoft" \
    year="1999" \
    media="download" \
    file1="../hhw/htmlhelp.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/itss.dll"

load_itss()
{
    # https://msdn.microsoft.com/en-us/library/windows/desktop/ms669985(v=vs.85).aspx
    w_download_to hhw ${W_DOWNLOADURLS}/htmlhelp.exe b2b3140d42a818870c1ab13c1c7b8d4536f22bd994fa90aade89729a6009a3ae

    w_try_cabextract -d "$W_TMP" -F hhupd.exe "$W_CACHE"/hhw/htmlhelp.exe
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -F itss.dll "$W_TMP"/hhupd.exe
    w_override_dlls native itss
    w_try_regsvr itss.dll
}

#----------------------------------------------------------------

w_metadata cinepak dlls \
    title="Cinepak Codec" \
    publisher="Radius" \
    year="1995" \
    media="download" \
    file1="cvid32.zip" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/iccvid.dll" \
    homepage="http://www.probo.com/cinepak.php"

load_cinepak()
{
    w_download "${W_DOWNLOADURLS}/cvid32.zip" a41984a954fe77557f228fa8a95cdc05db22bf9ff5429fe4307fd6fc51e11969

    if [ -f "$W_SYSTEM32_DLLS/iccvid.dll" ]; then
        w_try rm -f "$W_SYSTEM32_DLLS/iccvid.dll"
    fi

    w_try_unzip "$W_SYSTEM32_DLLS" "${W_CACHE}/${W_PACKAGE}/${file1}" ICCVID.DLL

    w_try mv -f "$W_SYSTEM32_DLLS/ICCVID.DLL" "$W_SYSTEM32_DLLS/iccvid.dll"

    w_override_dlls native iccvid
}

#----------------------------------------------------------------

w_metadata jet40 dlls \
    title="MS Jet 4.0 Service Pack 8" \
    publisher="Microsoft" \
    year="2003" \
    media="download" \
    file1="jet40sp8_9xnt.exe" \
    installed_file1="$W_COMMONFILES_WIN/Microsoft Shared/dao/dao360.dll"

load_jet40()
{
    # mdac27 is 32-bit only, so use mdac28 for win64:
    if [ "$W_ARCH" = "win64" ] ; then
        w_call mdac28
    else
        w_call mdac27
    fi
    w_call wsh57

    # https://support.microsoft.com/kb/239114
    # See also https://bugs.winehq.org/show_bug.cgi?id=6085
    # FIXME: "failed with error 2"
    w_download ${W_DOWNLOADURLS}/jet40sp8_9xnt.exe b060246cd499085a31f15873689d5fa7df817e407c8261a5c71fa6b9f7042560

    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try "$WINE" jet40sp8_9xnt.exe $W_UNATTENDED_SLASH_Q
}

# FIXME: verify_jet40()
# See https://github.com/Winetricks/winetricks/issues/327,
# https://en.wikibooks.org/wiki/JET_Database/Creating_and_connecting, and
# https://msdn.microsoft.com/en-us/library/ms677200%28v=vs.85%29.aspx

#----------------------------------------------------------------

w_metadata ie8_kb2936068 dlls \
    title="Cumulative Security Update for Internet Explorer 8" \
    publisher="Microsoft" \
    year="2014" \
    media="download" \
    file1="IE8-WindowsXP-KB2936068-x86-ENU.exe" \
    installed_file1="c:/windows/KB2936068-IE8.log"

load_ie8_kb2936068()
{
    # If we really need win64 support, should check if there's an x64 version of the hotfix
    w_package_unsupported_win64

    w_call ie8

    w_download ${W_DOWNLOADURLS}/IE8-WindowsXP-KB2936068-x86-ENU.exe 8bda23c78cdcd9d01c364a01c6d639dfb2d11550a5521b8a81c808c1a2b1824e

    if [ -n "$W_UNATTENDED_SLASH_Q" ]; then
        quiet="$W_UNATTENDED_SLASH_QUIET /forcerestart"
    else
        quiet=""
    fi

    

    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try_ms_installer "$WINE" IE8-WindowsXP-KB2936068-x86-ENU.exe $quiet

    w_set_winver 'default'
}
w_metadata ie8 dlls \
    title="Internet Explorer 8" \
    publisher="Microsoft" \
    year="2009" \
    media="download" \
    conflicts="ie6 ie7" \
    file1="IE8-WindowsXP-x86-ENU.exe" \
    installed_file1="c:/windows/ie8_main.log"

load_ie8()
{
    # Installer itself bails out
    w_package_unsupported_win64

    # Bundled in Windows 7, so refuses to install. Works with XP:
    w_set_winver winxp

    # Unregister Wine IE
    #if [ ! -f "$W_SYSTEM32_DLLS"/plugin.ocx ]; then
    if grep -q -i "wine placeholder" "$W_PROGRAMS_X86_UNIX/Internet Explorer/iexplore.exe"; then
        w_override_dlls builtin iexplore.exe
        w_try "$WINE" iexplore -unregserver
    fi

    w_call msls31

    # Change the override to the native so we are sure we use and register them
    w_override_dlls native,builtin ieframe ieproxy itircl itss jscript msctf mshtml shdoclc shdocvw shlwapi urlmon wininet xmllite

    # IE8 installer will check the version number of iexplore.exe which causes IE8 installer to fail on wine-1.9.0+
    w_override_dlls native iexplore.exe

    # Bundled updspapi cannot work on Wine
    w_override_dlls builtin updspapi

    # Remove the fake DLLs from the existing WINEPREFIX
    if [ -f "$W_PROGRAMS_X86_UNIX/Internet Explorer/iexplore.exe" ]; then
        w_try mv "$W_PROGRAMS_X86_UNIX/Internet Explorer/iexplore.exe" "$W_PROGRAMS_X86_UNIX/Internet Explorer/iexplore.exe.bak"
    fi

    for dll in browseui inseng itircl itss jscript msctf mshtml shdoclc shdocvw shlwapi urlmon; do
        test -f "$W_SYSTEM32_DLLS"/$dll.dll &&
            w_try mv "$W_SYSTEM32_DLLS"/$dll.dll "$W_SYSTEM32_DLLS"/$dll.dll.bak
    done

    # See https://bugs.winehq.org/show_bug.cgi?id=16013
    # Find instructions to create this file in dlls/wintrust/tests/crypt.c
    w_download ${W_DOWNLOADURLS}/IE8/winetest.cat 5d18ab44fc289100ccf4b51cf614cc2d36f7ca053e557e2ba973811293c97d38

    # Put a dummy catalog file in place
    mkdir -p "$W_SYSTEM32_DLLS"/catroot/\{f750e6c3-38ee-11d1-85e5-00c04fc295ee\}
    w_try cp -f "$W_CACHE"/ie8/winetest.cat "$W_SYSTEM32_DLLS"/catroot/\{f750e6c3-38ee-11d1-85e5-00c04fc295ee\}/oem0.cat

    w_download ${W_DOWNLOADURLS}/IE8/IE8-WindowsXP-x86-ENU.exe 5a2c6c82774bfe99b175f50a05b05bcd1fac7e9d0e54db2534049209f50cd6ef

    # KLUDGE: if / is writable (as on OS X?), having a Z: mapping to it
    # causes ie7 to put temporary directories on Z:\.
    # So hide it temporarily.  This is not very robust!
    if [ -w / ] && [ -h "$WINEPREFIX/dosdevices/z:" ]; then
        w_try rm -f "$WINEPREFIX/dosdevices/z:.bak_wt"
        w_try mv "$WINEPREFIX/dosdevices/z:" "$WINEPREFIX/dosdevices/z:.bak_wt"
        _W_restore_z=1
    fi

    w_try_cd "$W_CACHE/$W_PACKAGE"

    # FIXME: There's an option for /updates-noupdates to disable checking for updates, but that
    # forces the install to fail on Wine. Not sure if it's an IE8 or Wine bug...
    # FIXME: can't check status, as it always reports failure on wine?
    "$WINE" IE8-WindowsXP-x86-ENU.exe ${W_OPT_UNATTENDED:+/quiet /forcerestart}

    if [ "$_W_restore_z" = 1 ]; then
        # END KLUDGE: restore Z:, assuming that the user didn't kill us
        w_try mv "$WINEPREFIX/dosdevices/z:.bak_wt" "$WINEPREFIX/dosdevices/z:"
    fi

    # Work around DLL registration bug until ierunonce/RunOnce/wineboot is fixed
    # FIXME: whittle down this list
    w_try_cd "$W_SYSTEM32_DLLS"
    for i in actxprxy.dll browseui.dll browsewm.dll cdfview.dll ddraw.dll \
        dispex.dll dsound.dll iedkcs32.dll iepeers.dll iesetup.dll \
        imgutil.dll inetcomm.dll isetup.dll jscript.dll laprxy.dll \
        mlang.dll msctf.dll mshtml.dll mshtmled.dll msi.dll msimtf.dll msident.dll \
        msoeacct.dll msrating.dll mstime.dll msxml3.dll occache.dll \
        ole32.dll oleaut32.dll olepro32.dll pngfilt.dll quartz.dll \
        rpcrt4.dll rsabase.dll rsaenh.dll scrobj.dll scrrun.dll \
        shdocvw.dll shell32.dll urlmon.dll vbscript.dll webcheck.dll \
        wshcon.dll wshext.dll asctrls.ocx hhctrl.ocx mscomct2.ocx \
        plugin.ocx proctexe.ocx tdc.ocx uxtheme.dll webcheck.dll wshom.ocx; do
        "$WINE" regsvr32 /i $i > /dev/null 2>&1
    done

    if w_workaround_wine_bug 25648 "Setting TabProcGrowth=0 to avoid hang"; then
        cat > "$W_TMP"/set-tabprocgrowth.reg <<_EOF_
REGEDIT4
[HKEY_CURRENT_USER\\Software\\Microsoft\\Internet Explorer\\Main]
"TabProcGrowth"=dword:00000000
_EOF_
        w_try_regedit "$W_TMP_WIN"\\set-tabprocgrowth.reg
    fi

    # Builtin ieproxy is in system32, but ie8's lives in Program Files. Native
    # CLSID path will get overwritten on prefix update. Setting ieproxy to
    # native doesn't help because setupapi ignores DLL overrides. To work
    # around this problem, copy native ieproxy to system32.
    w_try cp -f "${W_PROGRAMS_X86_UNIX}/Internet Explorer/ieproxy.dll" "$W_SYSTEM32_DLLS"

    # Seeing is believing
    case $WINETRICKS_GUI in
        none)
            w_warn "To start ie8, use the command \"$WINE\" '${W_PROGRAMS_WIN}\\\\Internet Explorer\\\\iexplore'"
            ;;
        *)
            w_warn "Starting ie8.  To start it later, use the command \"$WINE\" '${W_PROGRAMS_WIN}\\\\Internet Explorer\\\\iexplore'"
            "$WINE" "${W_PROGRAMS_WIN}\\Internet Explorer\\iexplore" https://www.microsoft.com/windows/internet-explorer > /dev/null 2>&1 &
            ;;
    esac

    w_set_winver 'default'

    unset _W_restore_z
}
#----------------------------------------------------------------

w_metadata l3codecx dlls \
    title="MPEG Layer-3 Audio Codec for Microsoft DirectShow" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/l3codecx.ax"

load_l3codecx()
{
    helper_directx_dl

    w_try_cabextract -d "$W_TMP" -L -F dxnt.cab "$W_CACHE"/directx9/$DIRECTX_NAME
    w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'l3codecx.ax' "$W_TMP/dxnt.cab"

    w_try_regsvr l3codecx.ax
}

#----------------------------------------------------------------

# FIXME: installed location is
# $W_PROGRAMS_X86_WIN/Gemeinsame Dateien/System/ADO/msado26.tlb
# in German... need a variable W_COMMONFILES or something like that

w_metadata mdac27 dlls \
    title="Microsoft Data Access Components 2.7 sp1" \
    publisher="Microsoft" \
    year="2006" \
    media="download" \
    file1="MDAC_TYP_mdac27.EXE" \
    installed_file1="$W_COMMONFILES_X86_WIN/System/ADO/msado26.tlb"

load_mdac27()
{
    w_package_unsupported_win64

    # https://www.microsoft.com/downloads/en/details.aspx?FamilyId=9AD000F2-CAE7-493D-B0F3-AE36C570ADE8&displaylang=en
    # Originally at: https://download.microsoft.com/download/3/b/f/3bf74b01-16ba-472d-9a8c-42b2b4fa0d76/mdac_typ.exe
    # Mirror list: http://www.filewatcher.com/m/MDAC_TYP.EXE.5389224-0.html (5.14 MB MDAC_TYP.EXE)
    # 2018/08/09: ftp.gunadarma.ac.id is dead, moved to archive.org
    w_download ${W_DOWNLOADURLS}/MDAC_TYP_mdac27.EXE 36d2a3099e6286ae3fab181a502a95fbd825fa5ddb30bf09b345abc7f1f620b4

    load_native_mdac
    w_set_winver nt40
    w_try_cd "${W_CACHE}/${W_PACKAGE}"
    w_try "$WINE" "${file1}" ${W_OPT_UNATTENDED:+ /q /C:"setup $W_UNATTENDED_SLASH_QNT"}
    w_set_winver 'default'
}

#----------------------------------------------------------------

w_metadata mdac28 dlls \
    title="Microsoft Data Access Components 2.8 sp1" \
    publisher="Microsoft" \
    year="2005" \
    media="download" \
    file1="MDAC_TYP_mdac28.EXE" \
    installed_file1="$W_COMMONFILES_X86_WIN/System/ADO/msado27.tlb"

load_mdac28()
{
    # https://www.microsoft.com/en-us/download/details.aspx?id=5793
    w_download ${W_DOWNLOADURLS}/MDAC_TYP_mdac28.EXE 157ebae46932cb9047b58aa849ac1885e8cbd2f218810cb83e57613b49c679d6
    load_native_mdac
    w_set_winver nt40
    w_try_cd "$W_CACHE"/"$W_PACKAGE"
    w_try "$WINE" mdac_typ.exe ${W_OPT_UNATTENDED:+ /q /C:"setup $W_UNATTENDED_SLASH_QNT"}
    w_set_winver 'default'
}

#----------------------------------------------------------------

w_metadata mdx dlls \
    title="Managed DirectX" \
    publisher="Microsoft" \
    year="2006" \
    media="download" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="C:/windows/assembly/GAC/microsoft.directx/1.0.2902.0__31bf3856ad364e35/microsoft.directx.dll"

load_mdx()
{
    helper_directx_Jun2010

    w_try_cd "$W_TMP"

    w_try_cabextract -F "*MDX*" "$W_CACHE"/directx9/$DIRECTX_NAME
    w_try_cabextract -F "*.cab" ./*Archive.cab

    # Install assemblies
    w_try_cabextract -d "$W_WINDIR_UNIX/Microsoft.NET/DirectX for Managed Code/1.0.2902.0" -F "microsoft.directx*" ./*MDX1_x86.cab
    for file in mdx_*.cab; do
        ver="${file%%_x86.cab}"
        ver="${ver##mdx_}"
        w_try_cabextract -d "$W_WINDIR_UNIX/Microsoft.NET/DirectX for Managed Code/$ver" -F "microsoft.directx*" "$file"
    done
    w_try_cabextract -d "$W_WINDIR_UNIX/Microsoft.NET/DirectX for Managed Code/1.0.2911.0" -F "microsoft.directx.direct3dx*" ./*MDX1_x86.cab

    # Add them to GAC
    w_try_cd "$W_WINDIR_UNIX/Microsoft.NET/DirectX for Managed Code"
    for ver in *; do
        (
            w_try_cd "$ver"
            for asm in *.dll; do
                name="${asm%%.dll}"
                w_try mkdir -p "$W_WINDIR_UNIX/assembly/GAC/$name/${ver}__31bf3856ad364e35"
                w_try cp "$asm" "$W_WINDIR_UNIX/assembly/GAC/$name/${ver}__31bf3856ad364e35"
            done
        )
    done

    # AssemblyFolders
    cat > "$W_TMP"/asmfolders.reg <<_EOF_
REGEDIT4

[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NETFramework\\AssemblyFolders\\DX_1.0.2902.0]
@="C:\\\\windows\\\\Microsoft.NET\\\\DirectX for Managed Code\\\\1.0.2902.0\\\\"

[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NETFramework\\AssemblyFolders\\DX_1.0.2903.0]
@="C:\\\\windows\\\\Microsoft.NET\\\\DirectX for Managed Code\\\\1.0.2903.0\\\\"

[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NETFramework\\AssemblyFolders\\DX_1.0.2904.0]
@="C:\\\\windows\\\\Microsoft.NET\\\\DirectX for Managed Code\\\\1.0.2904.0\\\\"

[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NETFramework\\AssemblyFolders\\DX_1.0.2905.0]
@="C:\\\\windows\\\\Microsoft.NET\\\\DirectX for Managed Code\\\\1.0.2905.0\\\\"

[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NETFramework\\AssemblyFolders\\DX_1.0.2906.0]
@="C:\\\\windows\\\\Microsoft.NET\\\\DirectX for Managed Code\\\\1.0.2906.0\\\\"

[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NETFramework\\AssemblyFolders\\DX_1.0.2907.0]
@="C:\\\\windows\\\\Microsoft.NET\\\\DirectX for Managed Code\\\\1.0.2907.0\\\\"

[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NETFramework\\AssemblyFolders\\DX_1.0.2908.0]
@="C:\\\\windows\\\\Microsoft.NET\\\\DirectX for Managed Code\\\\1.0.2908.0\\\\"

[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NETFramework\\AssemblyFolders\\DX_1.0.2909.0]
@="C:\\\\windows\\\\Microsoft.NET\\\\DirectX for Managed Code\\\\1.0.2909.0\\\\"

[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NETFramework\\AssemblyFolders\\DX_1.0.2910.0]
@="C:\\\\windows\\\\Microsoft.NET\\\\DirectX for Managed Code\\\\1.0.2910.0\\\\"

[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\.NETFramework\\AssemblyFolders\\DX_1.0.2911.0]
@="C:\\\\windows\\\\Microsoft.NET\\\\DirectX for Managed Code\\\\1.0.2911.0\\\\"
_EOF_
    w_try_regedit "$W_TMP_WIN"\\asmfolders.reg
}

#----------------------------------------------------------------

w_metadata mf dlls \
    title="MS Media Foundation" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/mf.dll"

load_mf()
{
    helper_win7sp1 x86_microsoft-windows-mediafoundation_31bf3856ad364e35_6.1.7601.17514_none_9e6699276b03c38e/mf.dll
    w_try cp "$W_TMP/x86_microsoft-windows-mediafoundation_31bf3856ad364e35_6.1.7601.17514_none_9e6699276b03c38e/mf.dll" "$W_SYSTEM32_DLLS/mf.dll"

    if [ "$W_ARCH" = "win64" ]; then
        helper_win7sp1_x64 amd64_microsoft-windows-mediafoundation_31bf3856ad364e35_6.1.7601.17514_none_fa8534ab236134c4/mf.dll
        w_try cp "$W_TMP/amd64_microsoft-windows-mediafoundation_31bf3856ad364e35_6.1.7601.17514_none_fa8534ab236134c4/mf.dll" "$W_SYSTEM64_DLLS/mf.dll"
    fi

    w_override_dlls native,builtin mf
}

#----------------------------------------------------------------

w_metadata mfc40 dlls \
    title="MS mfc40 (Microsoft Foundation Classes from win7sp1)" \
    publisher="Microsoft" \
    year="1999" \
    media="download" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/mfc40.dll"

load_mfc40()
{
    helper_win7sp1 x86_microsoft-windows-mfc40_31bf3856ad364e35_6.1.7601.17514_none_5c06580240091047/mfc40.dll
    w_try cp "$W_TMP/x86_microsoft-windows-mfc40_31bf3856ad364e35_6.1.7601.17514_none_5c06580240091047/mfc40.dll" "$W_SYSTEM32_DLLS/mfc40.dll"

    helper_win7sp1 x86_microsoft-windows-mfc40u_31bf3856ad364e35_6.1.7601.17514_none_f51a7bf0b3d25294/mfc40u.dll
    w_try cp "$W_TMP/x86_microsoft-windows-mfc40u_31bf3856ad364e35_6.1.7601.17514_none_f51a7bf0b3d25294/mfc40u.dll" "$W_SYSTEM32_DLLS/mfc40u.dll"

    w_call msvcrt40
}

#----------------------------------------------------------------

w_metadata msacm32 dlls \
    title="MS ACM32" \
    publisher="Microsoft" \
    year="2003" \
    media="download" \
    file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/msacm32.dll"

load_msacm32()
{
    helper_winxpsp3 i386/msacm32.dl_
    w_try_cabextract --directory="$W_SYSTEM32_DLLS" "$W_TMP"/i386/msacm32.dl_
    w_override_dlls native,builtin msacm32
}

#----------------------------------------------------------------

w_metadata msasn1 dlls \
    title="MS ASN1" \
    publisher="Microsoft" \
    year="2003" \
    media="download" \
    file1="../win2ksp4/W2KSP4_EN.EXE" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/msasn1.dll"

load_msasn1()
{
    helper_win2ksp4 i386/msasn1.dl_
    w_try_cabextract --directory="$W_SYSTEM32_DLLS" "$W_TMP"/i386/msasn1.dl_
}

#----------------------------------------------------------------

w_metadata msctf dlls \
    title="MS Text Service Module" \
    publisher="Microsoft" \
    year="2003" \
    media="download" \
    file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/msctf.dll"

load_msctf()
{
    helper_winxpsp3 i386/msctf.dl_
    w_try_cabextract --directory="$W_SYSTEM32_DLLS" "$W_TMP"/i386/msctf.dl_
    w_override_dlls native,builtin msctf
}

#----------------------------------------------------------------

w_metadata msdelta dlls \
    title="MSDelta differential compression library" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/msdelta.dll"

load_msdelta()
{
    helper_win7sp1 x86_microsoft-windows-servicingstack_31bf3856ad364e35_6.1.7601.17514_none_0b66cb34258c936f/msdelta.dll
    w_try cp "$W_TMP/x86_microsoft-windows-servicingstack_31bf3856ad364e35_6.1.7601.17514_none_0b66cb34258c936f/msdelta.dll" "$W_SYSTEM32_DLLS/msdelta.dll"

    if [ "$W_ARCH" = "win64" ]; then
        helper_win7sp1_x64 amd64_microsoft-windows-servicingstack_31bf3856ad364e35_6.1.7601.17514_none_678566b7ddea04a5/msdelta.dll
        w_try cp "$W_TMP/amd64_microsoft-windows-servicingstack_31bf3856ad364e35_6.1.7601.17514_none_678566b7ddea04a5/msdelta.dll" "$W_SYSTEM64_DLLS/msdelta.dll"
    fi

    w_override_dlls native,builtin msdelta
}

#----------------------------------------------------------------

w_metadata msdxmocx dlls \
    title="MS Windows Media Player 2 ActiveX control for VB6" \
    publisher="Microsoft" \
    year="1999" \
    media="download" \
    file1="mpfull.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/msdxm.ocx"

load_msdxmocx()
{
    # Previously at https://www.oldapps.com/windows_media_player.php?old_windows_media_player=3?download
    # 2015/12/01: Iceweasel gave a security warning (!), but clamscan and virustotal.com report it as clean
    #
    # 2016/02/18: Since then, oldapps.com removed it. It's on a Finnish mirror, where it's been since 2001/10/20
    # Found using http://www.filewatcher.com/m/mpfull.exe.3593680-0.html
    # The sha256sum is different. Perhaps Iceweasel was right. This one is also clean according to clamscan/virustotal.com

    # 2017/09/28: define.fi is down, these sites have mpfull.exe with the original sha256:
    # http://hell.pl/agnus/windows95/
    # http://zerosky.oldos.org/win9x.html
    # https://sdfox7.com/win95/

    w_download ${W_DOWNLOADURLS}/mpfull.exe a39b2b9735cedd513fcb78f8634695d35073e9d7e865e536a0da6db38c7225e4

    w_try_cabextract --directory="$W_SYSTEM32_DLLS" "$W_CACHE/$W_PACKAGE/${file1}"
    w_try_regsvr msdxm.ocx
}

#----------------------------------------------------------------

w_metadata msflxgrd dlls \
    title="MS FlexGrid Control (msflxgrd.ocx)" \
    publisher="Microsoft" \
    year="2012" \
    media="download" \
    file1="../vb6sp6/VB60SP6-KB2708437-x86-ENU.msi" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/msflxgrd.ocx"

load_msflxgrd()
{
    helper_vb6sp6 "$W_TMP" MSFlxGrd.ocx
    w_try mv "${W_TMP}/MSFlxGrd.ocx" "$W_SYSTEM32_DLLS/msflxgrd.ocx"
    w_try_regsvr msflxgrd.ocx
}

#----------------------------------------------------------------

w_metadata mshflxgd dlls \
    title="MS Hierarchical FlexGrid Control (mshflxgd.ocx)" \
    publisher="Microsoft" \
    year="2012" \
    media="download" \
    file1="../vb6sp6/VB60SP6-KB2708437-x86-ENU.msi" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/mshflxgd.ocx"

load_mshflxgd()
{
    helper_vb6sp6 "$W_TMP" MShflxgd.ocx
    w_try mv "${W_TMP}/MShflxgd.ocx" "$W_SYSTEM32_DLLS/mshflxgd.ocx"
    w_try_regsvr mshflxgd.ocx
}

#----------------------------------------------------------------

w_metadata mspatcha dlls \
    title="MS mspatcha" \
    publisher="Microsoft" \
    year="2004" \
    media="download" \
    file1="../win2ksp4/W2KSP4_EN.EXE" \
    installed_exe1="$W_SYSTEM32_DLLS_WIN/mspatcha.dll"

load_mspatcha()
{
    helper_win2ksp4 i386/mspatcha.dl_
    w_try_cabextract --directory="$W_SYSTEM32_DLLS" "$W_TMP"/i386/mspatcha.dl_

    w_override_dlls native,builtin mspatcha
}

#----------------------------------------------------------------

w_metadata msscript dlls \
    title="MS Windows Script Control" \
    publisher="Microsoft" \
    year="2004" \
    media="download" \
    file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/msscript.ocx"

load_msscript()
{
    helper_winxpsp3 i386/msscript.oc_
    w_try_cabextract --directory="$W_SYSTEM32_DLLS" "$W_TMP"/i386/msscript.oc_
    w_override_dlls native,builtin i386/msscript.ocx
}

#----------------------------------------------------------------

w_metadata msls31 dlls \
    title="MS Line Services" \
    publisher="Microsoft" \
    year="2001" \
    media="download" \
    file1="InstMsiW.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/msls31.dll"

load_msls31()
{
    # Needed by native RichEdit and Internet Explorer
    # Originally at https://download.microsoft.com/download/WindowsInstaller/Install/2.0/NT45/EN-US/InstMsiW.exe
    # Mirror list at http://www.filewatcher.com/m/InstMsiW.exe.1822848-0.html
    w_download ${W_DOWNLOADURLS}/InstMsiW.exe 4c3516c0b5c2b76b88209b22e3bf1cb82d8e2de7116125e97e128952372eed6b InstMsiW.exe

    w_try_cabextract --directory="$W_TMP" "$W_CACHE"/msls31/InstMsiW.exe
    w_try cp -f "$W_TMP"/msls31.dll "$W_SYSTEM32_DLLS"
}

#----------------------------------------------------------------

w_metadata msmask dlls \
    title="MS Masked Edit Control" \
    publisher="Microsoft" \
    year="2009" \
    media="download" \
    file1="../vb6sp6/VB60SP6-KB2708437-x86-ENU.msi" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/msmask32.ocx"

load_msmask()
{
    helper_vb6sp6 "$W_TMP" msmask32.ocx
    w_try mv "${W_TMP}/msmask32.ocx" "$W_SYSTEM32_DLLS/msmask32.ocx"
    w_try_regsvr msmask32.ocx
}

 #----------------------------------------------------------------

w_metadata msftedit dlls \
    title="Microsoft RichEdit Control" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/msftedit.dll"

load_msftedit()
{
    helper_win7sp1 x86_microsoft-windows-msftedit_31bf3856ad364e35_6.1.7601.17514_none_d7d862f19573a5ff/msftedit.dll
    w_try cp "$W_TMP/x86_microsoft-windows-msftedit_31bf3856ad364e35_6.1.7601.17514_none_d7d862f19573a5ff/msftedit.dll" "$W_SYSTEM32_DLLS/msftedit.dll"

    if [ "$W_ARCH" = "win64" ]; then
        helper_win7sp1_x64 amd64_microsoft-windows-msftedit_31bf3856ad364e35_6.1.7601.17514_none_33f6fe754dd11735/msftedit.dll
        w_try cp "$W_TMP/amd64_microsoft-windows-msftedit_31bf3856ad364e35_6.1.7601.17514_none_33f6fe754dd11735/msftedit.dll" "$W_SYSTEM64_DLLS/msftedit.dll"
    fi

    w_override_dlls native,builtin msftedit
}

#----------------------------------------------------------------

w_metadata msvcrt40 dlls \
    title="fixme" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/msvcrt40.dll"

load_msvcrt40()
{
    helper_winxpsp3 i386/msvcrt40.dl_
    w_try_cabextract --directory="$W_SYSTEM32_DLLS" "$W_TMP"/i386/msvcrt40.dl_

    w_override_dlls native,builtin msvcrt40
}

#----------------------------------------------------------------

w_metadata msxml3 dlls \
    title="MS XML Core Services 3.0" \
    publisher="Microsoft" \
    year="2005" \
    media="download" \
    file1="msxml3.msi" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/msxml3.dll"

load_msxml3()
{
    # Service Pack 7
    # Originally at https://download.microsoft.com/download/8/8/8/888f34b7-4f54-4f06-8dac-fa29b19f33dd/msxml3.msi
    # Mirror list: http://www.filewatcher.com/m/msxml3.msi.1070592-0.html
    # Known bad sites (2017/06/11):
    # ftp://support.danbit.dk/D/DVD-RW-USB2B/Driver/Installation/Data/Redist/msxml3.msi
    # ftp://94.79.56.169/common/Client/MSXML%204.0%20Service%20Pack%202/msxml3.msi
    w_download ${W_DOWNLOADURLS}/msxml3.msi f9c678f8217e9d4f9647e8a1f6d89a7c26a57b9e9e00d39f7487493dd7b4e36c

    # It won't install on top of Wine's msxml3, which has a pretty high version number, so delete Wine's fake DLL
    rm "$W_SYSTEM32_DLLS"/msxml3.dll
    w_override_dlls native msxml3
    w_try_cd "$W_CACHE/$W_PACKAGE"

    # See https://github.com/Winetricks/winetricks/issues/1086
    # and https://bugs.winehq.org/show_bug.cgi?id=26925
    if w_workaround_wine_bug 26925 "Forcing quiet install"; then
        w_try "$WINE" msiexec /i msxml3.msi /q
    else
        w_try "$WINE" msiexec /i msxml3.msi $W_UNATTENDED_SLASH_Q
    fi
}

#----------------------------------------------------------------

w_metadata msxml4 dlls \
    title="MS XML Core Services 4.0" \
    publisher="Microsoft" \
    year="2009" \
    media="download" \
    file1="msxml.msi" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/msxml4.dll"

load_msxml4()
{
    # MS06-071: https://www.microsoft.com/en-us/download/details.aspx?id=11125
    # w_download https://download.microsoft.com/download/e/2/e/e2e92e52-210b-4774-8cd9-3a7a0130141d/msxml4-KB927978-enu.exe 7602c2a6d2a46ef2b4028438d2cce67fe437a9bfb569249ea38141b4756b4e03
    # MS07-042: https://www.microsoft.com/en-us/download/details.aspx?id=2386
    # w_download https://download.microsoft.com/download/9/4/2/9422e6b6-08ee-49cb-9f05-6c6ee755389e/msxml4-KB936181-enu.exe 1ce9ff868816cfc9bf33e93fdf1552afce5b491443892babb521e74c05e45242
    # SP3 (2009): https://www.microsoft.com/en-us/download/details.aspx?id=15697
    w_download ${W_DOWNLOADURLS}/msxml.msi 47c2ae679c37815da9267c81fc3777de900ad2551c11c19c2840938b346d70bb
    w_override_dlls native,builtin msxml4
    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try "$WINE" msiexec /i msxml.msi $W_UNATTENDED_SLASH_Q
}

#----------------------------------------------------------------

w_metadata msxml6 dlls \
    title="MS XML Core Services 6.0 sp2" \
    publisher="Microsoft" \
    year="2009" \
    media="download" \
    file1="msxml6-KB973686-enu-amd64.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/msxml6.dll"

load_msxml6()
{
    # Service Pack 2
    # https://www.microsoft.com/en-us/download/details.aspx?id=9774

    # 64bit exe also includes 32bit dlls
    w_download ${W_DOWNLOADURLS}/msxml6-KB973686-enu-amd64.exe 59a4bdb42d762d3d27cc842eb3becb687a234127b0b22b752536d77fd9694f5b

    w_try_cabextract --directory="${W_TMP}" "${W_CACHE}"/msxml6/msxml6-KB973686-enu-amd64.exe
    w_try_cabextract --directory="${W_TMP}" "${W_TMP}"/msxml6.msi
    w_try cp -f "${W_TMP}"/msxml6.dll.86F857F6_A743_463D_B2FE_98CB5F727E09 "$W_SYSTEM32_DLLS"/msxml6.dll
    w_try cp -f "${W_TMP}"/msxml6r.dll.86F857F6_A743_463D_B2FE_98CB5F727E09 "$W_SYSTEM32_DLLS"/msxml6r.dll

    if [ "$W_ARCH" = "win64" ]; then
        w_try cp -f "${W_TMP}"/msxml6.dll.1ECC0691_D2EB_4A33_9CBF_5487E5CB17DB "$W_SYSTEM64_DLLS"/msxml6.dll
        w_try cp -f "${W_TMP}"/msxml6r.dll.1ECC0691_D2EB_4A33_9CBF_5487E5CB17DB "$W_SYSTEM64_DLLS"/msxml6r.dll
    fi

    w_override_dlls native,builtin msxml6
}

#----------------------------------------------------------------

w_metadata nuget dlls \
    title="NuGet Package manager" \
    publisher="Outercurve Foundation" \
    year="2013" \
    media="download" \
    file1="nuget.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/nuget.exe" \
    homepage="https://nuget.org"

load_nuget()
{
    w_call dotnet40
    # Changes too rapidly to check shasum
    w_download https://nuget.org/nuget.exe
    w_try cp "$W_CACHE/$W_PACKAGE"/nuget.exe "$W_SYSTEM32_DLLS"
    w_warn "To run NuGet, use the command line \"$WINE nuget\"."
}

#----------------------------------------------------------------

w_metadata ogg dlls \
    title="OpenCodecs 0.85: FLAC, Speex, Theora, Vorbis, WebM" \
    publisher="Xiph.Org Foundation" \
    year="2011" \
    media="download" \
    file1="opencodecs_0.85.17777.exe" \
    installed_file1="$W_PROGRAMS_X86_WIN/Xiph.Org/Open Codecs/AxPlayer.dll" \
    homepage="https://xiph.org/dshow"

load_ogg()
{
    w_download ${W_DOWNLOADURLS}/opencodecs_0.85.17777.exe fcec3cea637e806501aff447d902de3b5bfef226b629e43ab67e46dbb23f13e7
    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try "$WINE" "$file1" $W_UNATTENDED_SLASH_S
}


#----------------------------------------------------------------

w_metadata ole32 dlls \
    title="MS ole32 Module (ole32.dll)" \
    publisher="Microsoft" \
    year="2004" \
    media="download" \
    file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/ole32.dll"

load_ole32()
{
    # Some applications need this, for example Wechat.
    helper_winxpsp3 i386/ole32.dl_
    w_try_cabextract --directory="$W_SYSTEM32_DLLS" "$W_TMP"/i386/ole32.dl_
    w_override_dlls native,builtin ole32
}

#----------------------------------------------------------------

w_metadata oleaut32 dlls \
    title="MS oleaut32.dll" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/oleaut32.dll"

load_oleaut32()
{
    helper_win7sp1 x86_microsoft-windows-ole-automation_31bf3856ad364e35_6.1.7601.17514_none_bf07947959bc4c33/oleaut32.dll
    w_try cp "$W_TMP/x86_microsoft-windows-ole-automation_31bf3856ad364e35_6.1.7601.17514_none_bf07947959bc4c33/oleaut32.dll" "$W_SYSTEM32_DLLS/oleaut32.dll"

    if [ "$W_ARCH" = "win64" ]; then
        helper_win7sp1_x64 amd64_microsoft-windows-ole-automation_31bf3856ad364e35_6.1.7601.17514_none_1b262ffd1219bd69/oleaut32.dll
        w_try cp "$W_TMP/amd64_microsoft-windows-ole-automation_31bf3856ad364e35_6.1.7601.17514_none_1b262ffd1219bd69/oleaut32.dll" "$W_SYSTEM64_DLLS/oleaut32.dll"
    fi

    w_override_dlls native,builtin oleaut32
}

#----------------------------------------------------------------

w_metadata pdh dlls \
    title="MS pdh.dll (Performance Data Helper)" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/pdh.dll"

load_pdh()
{
    helper_win7sp1 x86_microsoft-windows-p..rastructureconsumer_31bf3856ad364e35_6.1.7601.17514_none_b5e3f88a8eb425e8/pdh.dll
    w_try cp "$W_TMP/x86_microsoft-windows-p..rastructureconsumer_31bf3856ad364e35_6.1.7601.17514_none_b5e3f88a8eb425e8/pdh.dll" "$W_SYSTEM32_DLLS/pdh.dll"

    if [ "$W_ARCH" = "win64" ]; then
        helper_win7sp1_x64 amd64_microsoft-windows-p..rastructureconsumer_31bf3856ad364e35_6.1.7601.17514_none_1202940e4711971e/pdh.dll
        w_try cp "$W_TMP/amd64_microsoft-windows-p..rastructureconsumer_31bf3856ad364e35_6.1.7601.17514_none_1202940e4711971e/pdh.dll" "$W_SYSTEM64_DLLS/pdh.dll"
    fi

    w_override_dlls native,builtin pdh
}

#----------------------------------------------------------------

w_metadata peverify dlls \
    title="MS peverify (from .NET 2.0 SDK)" \
    publisher="Microsoft" \
    year="2006" \
    media="download" \
    file1="../dotnet20sdk/setup.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/peverify.exe"

load_peverify()
{
    w_download_to dotnet20sdk ${W_DOWNLOADURLS}/peverify.exe 1d7337bfbb2c65f43c82d188688ce152af403bcb67a2cc2a3cc68a580ecd8200

    # Seems to require dotnet20; at least doesn't work if dotnet40 is installed instead
    w_call dotnet20

    w_try_cabextract --directory="${W_TMP}" "${W_CACHE}/dotnet20sdk/setup.exe" -F netfxsd1.cab
    w_try_cabextract --directory="${W_TMP}" "${W_TMP}/netfxsd1.cab" -F FL_PEVerify_exe_____X86.3643236F_FC70_11D3_A536_0090278A1BB8
    w_try mv "${W_TMP}/FL_PEVerify_exe_____X86.3643236F_FC70_11D3_A536_0090278A1BB8" "${W_SYSTEM32_DLLS}/peverify.exe"
}

#----------------------------------------------------------------

w_metadata physx dlls \
    title="PhysX" \
    publisher="Nvidia" \
    year="2014" \
    media="download" \
    file1="PhysX-9.14.0702-SystemSoftware.msi" \
    installed_file1="$W_PROGRAMS_X86_WIN/NVIDIA Corporation/PhysX/Engine/v2.8.3/PhysXCore.dll"

load_physx()
{
    w_download ${W_DOWNLOADURLS}/PhysX-9.14.0702-SystemSoftware.msi 0a022e28accf5851be9d6577487cdcd3d3a3e2a8a21a64456b72b415c217f03c
    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try "$WINE" msiexec /i PhysX-9.14.0702-SystemSoftware.msi $W_UNATTENDED_SLASH_Q
}

#----------------------------------------------------------------

w_metadata pngfilt dlls \
    title="pngfilt.dll (from winxp)" \
    publisher="Microsoft" \
    year="2004" \
    media="download" \
    file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/pngfilt.dll"

load_pngfilt()
{
    # Previously used https://www.microsoft.com/en-us/download/details.aspx?id=3907
    # Now using winxp's dll

    helper_winxpsp3 i386/pngfilt.dl_
    w_try_cabextract --directory="$W_SYSTEM32_DLLS" "$W_TMP"/i386/pngfilt.dl_
    w_try_regsvr pngfilt.dll
}

#----------------------------------------------------------------

w_metadata prntvpt dlls \
    title="prntvpt.dll" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/prntvpt.dll"

load_prntvpt()
{

    helper_win7sp1 x86_microsoft-windows-p..g-printticket-win32_31bf3856ad364e35_6.1.7601.17514_none_1562129afd710f2c/prntvpt.dll
    w_try cp "$W_TMP/x86_microsoft-windows-p..g-printticket-win32_31bf3856ad364e35_6.1.7601.17514_none_1562129afd710f2c/prntvpt.dll" "$W_SYSTEM32_DLLS/prntvpt.dll"

    w_override_dlls native,builtin prntvpt
    w_try_regsvr prntvpt.dll

    if [ "$W_ARCH" = "win64" ]; then
        helper_win7sp1_x64 amd64_microsoft-windows-p..g-printticket-win32_31bf3856ad364e35_6.1.7601.17514_none_7180ae1eb5ce8062/prntvpt.dll
        w_try cp "$W_TMP/x86_microsoft-windows-p..g-printticket-win32_31bf3856ad364e35_6.1.7601.17514_none_1562129afd710f2c/prntvpt.dll" "$W_SYSTEM64_DLLS/prntvpt.dll"
        w_try_regsvr64 prntvpt.dll
    fi
}

#----------------------------------------------------------------

w_metadata python26 dlls \
    title="Python interpreter 2.6.2" \
    publisher="Python Software Foundaton" \
    year="2009" \
    media="download" \
    file1="python-2.6.2.msi" \
    installed_exe1="c:/Python26/python.exe"

load_python26()
{
    w_download ${W_DOWNLOADURLS}/python-2.6.2.msi c2276b398864b822c25a7c240cb12ddb178962afd2e12d602f1a961e31ad52ff
    w_download ${W_DOWNLOADURLS}/pywin32-214.win32-py2.6.exe dc311bbdc5868e3dd139dfc46136221b7f55c5613a98a5a48fa725a6c681cd40

    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try "$WINE" msiexec /i python-2.6.2.msi ALLUSERS=1 $W_UNATTENDED_SLASH_Q

    w_ahk_do "
        SetTitleMatchMode, 2
        run pywin32-214.win32-py2.6.exe
        WinWait, Setup, Wizard will install pywin32
        if ( w_opt_unattended > 0 ) {
             ControlClick Button2   ; next
             WinWait, Setup, Python 2.6 is required
             ControlClick Button3   ; next
             WinWait, Setup, Click Next to begin
             ControlClick Button3   ; next
             WinWait, Setup, finished
             ControlClick Button4   ; Finish
        }
        WinWaitClose
        "
}

#----------------------------------------------------------------

w_metadata python27 dlls \
    title="Python interpreter 2.7.16" \
    publisher="Python Software Foundaton" \
    year="2019" \
    media="download" \
    file1="python-2.7.16.msi" \
    installed_exe1="c:/Python27/python.exe"

load_python27()
{
    w_download ${W_DOWNLOADURLS}/python-2.7.16.msi d57dc3e1ba490aee856c28b4915d09e3f49442461e46e481bc6b2d18207831d7
    w_download ${W_DOWNLOADURLS}/pywin32-224.win32-py2.7.exe 03bb02aff0ec604d1d5fefc699581ab599fff618eaddc8a721f2fa22e5572dd4

    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try "$WINE" msiexec /i python-2.7.16.msi ALLUSERS=1 $W_UNATTENDED_SLASH_Q

    w_ahk_do "
        SetTitleMatchMode, 2
        run pywin32-224.win32-py2.7.exe
        WinWait, Setup, Wizard will install pywin32
        if ( w_opt_unattended > 0 ) {
             ControlClick Button2   ; next
             WinWait, Setup, Python 2.7 is required
             ControlClick Button3   ; next
             WinWait, Setup, Click Next to begin
             ControlClick Button3   ; next
             WinWait, Setup, finished
             ControlClick Button4   ; Finish
        }
        WinWaitClose
        "
}

#----------------------------------------------------------------

w_metadata qasf dlls \
    title="qasf.dll" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/qasf.dll"

load_qasf()
{
    helper_win7sp1 x86_microsoft-windows-directshow-asf_31bf3856ad364e35_6.1.7601.17514_none_1cc4e9c15ccc8ae8/qasf.dll
    w_try cp "$W_TMP/x86_microsoft-windows-directshow-asf_31bf3856ad364e35_6.1.7601.17514_none_1cc4e9c15ccc8ae8/qasf.dll" "$W_SYSTEM32_DLLS/qasf.dll"

    w_override_dlls native,builtin qasf
    w_try_regsvr qasf.dll

    if [ "$W_ARCH" = "win64" ]; then
        helper_win7sp1_x64 amd64_microsoft-windows-directshow-asf_31bf3856ad364e35_6.1.7601.17514_none_78e385451529fc1e/qasf.dll
        w_try cp "$W_TMP/amd64_microsoft-windows-directshow-asf_31bf3856ad364e35_6.1.7601.17514_none_78e385451529fc1e/qasf.dll" "$W_SYSTEM64_DLLS/qasf.dll"
        w_try_regsvr64 qasf.dll
    fi
}

#----------------------------------------------------------------

w_metadata qcap dlls \
    title="qcap.dll" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/qcap.dll"

load_qcap()
{
    helper_win7sp1 x86_microsoft-windows-directshow-capture_31bf3856ad364e35_6.1.7601.17514_none_bae08d1e7dcccf2a/qcap.dll
    w_try cp "$W_TMP/x86_microsoft-windows-directshow-capture_31bf3856ad364e35_6.1.7601.17514_none_bae08d1e7dcccf2a/qcap.dll" "$W_SYSTEM32_DLLS/qcap.dll"
    w_override_dlls native,builtin qcap
    w_try_regsvr qcap.dll

    if [ "$W_ARCH" = "win64" ]; then
        helper_win7sp1_x64 amd64_microsoft-windows-directshow-capture_31bf3856ad364e35_6.1.7601.17514_none_16ff28a2362a4060/qcap.dll
        w_try cp "$W_TMP/amd64_microsoft-windows-directshow-capture_31bf3856ad364e35_6.1.7601.17514_none_16ff28a2362a4060/qcap.dll" "$W_SYSTEM64_DLLS/qcap.dll"
        w_try_regsvr64 qcap.dll
    fi
}

#----------------------------------------------------------------

w_metadata qdvd dlls \
    title="qdvd.dll" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/qdvd.dll"

load_qdvd()
{
    helper_win7sp1 x86_microsoft-windows-directshow-dvdsupport_31bf3856ad364e35_6.1.7601.17514_none_562994bd321aac67/qdvd.dll
    w_try cp "$W_TMP/x86_microsoft-windows-directshow-dvdsupport_31bf3856ad364e35_6.1.7601.17514_none_562994bd321aac67/qdvd.dll" "$W_SYSTEM32_DLLS/qdvd.dll"
    w_override_dlls native,builtin qdvd
    w_try_regsvr qdvd.dll

    if [ "$W_ARCH" = "win64" ]; then
        helper_win7sp1_x64 amd64_microsoft-windows-directshow-dvdsupport_31bf3856ad364e35_6.1.7601.17514_none_b2483040ea781d9d/qdvd.dll
        w_try cp "$W_TMP/amd64_microsoft-windows-directshow-dvdsupport_31bf3856ad364e35_6.1.7601.17514_none_b2483040ea781d9d/qdvd.dll" "$W_SYSTEM64_DLLS/qdvd.dll"
        w_try_regsvr64 qdvd.dll
    fi
}

#----------------------------------------------------------------

w_metadata qedit dlls \
    title="qedit.dll" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/qedit.dll"

load_qedit()
{
    helper_win7sp1 x86_microsoft-windows-qedit_31bf3856ad364e35_6.1.7601.17514_none_5ca34698a5a970d2/qedit.dll
    w_try cp "$W_TMP/x86_microsoft-windows-qedit_31bf3856ad364e35_6.1.7601.17514_none_5ca34698a5a970d2/qedit.dll" "$W_SYSTEM32_DLLS/qedit.dll"
    w_override_dlls native,builtin qedit
    w_try_regsvr qedit.dll

    if [ "$W_ARCH" = "win64" ]; then
        helper_win7sp1_x64 amd64_microsoft-windows-qedit_31bf3856ad364e35_6.1.7601.17514_none_b8c1e21c5e06e208/qedit.dll
        w_try cp "$W_TMP/amd64_microsoft-windows-qedit_31bf3856ad364e35_6.1.7601.17514_none_b8c1e21c5e06e208/qedit.dll" "$W_SYSTEM64_DLLS/qedit.dll"
        w_try_regsvr64 qedit.dll
    fi
}

#----------------------------------------------------------------

w_metadata quartz dlls \
    title="quartz.dll" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/quartz.dll"

load_quartz()
{
    helper_win7sp1 x86_microsoft-windows-directshow-core_31bf3856ad364e35_6.1.7601.17514_none_a877a1cc4c284497/quartz.dll
    w_try cp "$W_TMP/x86_microsoft-windows-directshow-core_31bf3856ad364e35_6.1.7601.17514_none_a877a1cc4c284497/quartz.dll" "$W_SYSTEM32_DLLS/quartz.dll"
    w_override_dlls native,builtin quartz
    w_try_regsvr quartz.dll

    if [ "$W_ARCH" = "win64" ]; then
        helper_win7sp1_x64 amd64_microsoft-windows-directshow-core_31bf3856ad364e35_6.1.7601.17514_none_04963d500485b5cd/quartz.dll
        w_try cp "$W_TMP/amd64_microsoft-windows-directshow-core_31bf3856ad364e35_6.1.7601.17514_none_04963d500485b5cd/quartz.dll" "$W_SYSTEM64_DLLS/quartz.dll"
        w_try_regsvr64 quartz.dll
    fi
}

#----------------------------------------------------------------

w_metadata quicktime72 dlls \
    title="Apple QuickTime 7.2" \
    publisher="Apple" \
    year="2010" \
    media="download" \
    file1="QuickTimeInstaller.exe" \
    installed_file1="c:/windows/Installer/{95A890AA-B3B1-44B6-9C18-A8F7AB3EE7FC}/QTPlayer.ico"

load_quicktime72()
{
    # https://support.apple.com/kb/DL837
    w_download ${W_DOWNLOADURLS}/QuickTimeInstaller.exe a42b93531910bdf1539cc5ae3199ade5a1ca63fd4ac971df74c345d8e1ee6593

    w_try_cd "$W_CACHE"/"$W_PACKAGE"
    w_try "$WINE" "$file1" ALLUSERS=1 DESKTOP_SHORTCUTS=0 QTTaskRunFlags=0 QTINFO.BISQTPRO=1 SCHEDULE_ASUW=0 REBOOT_REQUIRED=No $W_UNATTENDED_SLASH_QN > /dev/null 2>&1

    if w_workaround_wine_bug 11681; then
        # Following advice verified with test movies from
        # https://support.apple.com/kb/HT1425
        # in QuickTimePlayer.

        case $LANG in
            ru*) w_warn "В настройках Quicktime включите Дополнительно / Безопасный режим (только gdi), иначе видеофайлы не будут воспроизводиться." ;;
            *) w_warn "In Quicktime preferences, check Advanced / Safe Mode (gdi), or movies won't play." ;;
        esac
        if test "$W_UNATTENDED_SLASH_Q" = ""; then
            w_try "$WINE" control "$W_PROGRAMS_WIN\\QuickTime\\QTSystem\\QuickTime.cpl"
        else
            # FIXME: script the control panel with AutoHotKey?
            # We could probably also overwrite QuickTime.qtp but
            # the format isn't known, so we'd have to override all other settings, too.
            :
        fi
    fi
}

#----------------------------------------------------------------

w_metadata quicktime76 dlls \
    title="Apple QuickTime 7.6" \
    publisher="Apple" \
    year="2010" \
    media="download" \
    file1="QuickTimeInstaller.exe" \
    installed_file1="c:/windows/Installer/{57752979-A1C9-4C02-856B-FBB27AC4E02C}/QTPlayer.ico"

load_quicktime76()
{
    # https://support.apple.com/kb/DL837
    w_download ${W_DOWNLOADURLS}/QuickTimeInstaller.exe c2dcda76ed55428e406ad7e6acdc84e804d30752a1380c313394c09bb3e27f56

    w_try_cd "$W_CACHE"/"$W_PACKAGE"
    w_try "$WINE" QuickTimeInstaller.exe ALLUSERS=1 DESKTOP_SHORTCUTS=0 QTTaskRunFlags=0 QTINFO.BISQTPRO=1 SCHEDULE_ASUW=0 REBOOT_REQUIRED=No $W_UNATTENDED_SLASH_QN > /dev/null 2>&1

    if w_workaround_wine_bug 11681; then
        # Following advice verified with test movies from
        # https://support.apple.com/kb/HT1425
        # in QuickTimePlayer.

        case $LANG in
            ru*) w_warn "В настройках Quicktime включите Дополнительно / Безопасный режим (только gdi), иначе видеофайлы не будут воспроизводиться." ;;
            *) w_warn "In Quicktime preferences, check Advanced / Safe Mode (gdi), or movies won't play." ;;
        esac
        if test "$W_UNATTENDED_SLASH_Q" = ""; then
            w_try "$WINE" control "$W_PROGRAMS_WIN\\QuickTime\\QTSystem\\QuickTime.cpl"
        else
            # FIXME: script the control panel with AutoHotKey?
            # We could probably also overwrite QuickTime.qtp but
            # the format isn't known, so we'd have to override all other settings, too.
            :
        fi
    fi
}

#----------------------------------------------------------------

w_metadata riched20 dlls \
    title="MS RichEdit Control 2.0 (riched20.dll)" \
    publisher="Microsoft" \
    year="2004" \
    media="download" \
    file1="../win2ksp4/W2KSP4_EN.EXE" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/riched20.dll"

load_riched20()
{
    # FIXME: this verb used to also install riched32.  Does anyone need that?
    helper_win2ksp4 i386/riched20.dl_
    w_try_cabextract --directory="$W_SYSTEM32_DLLS" "$W_TMP"/i386/riched20.dl_
    w_override_dlls native,builtin riched20

    # https://github.com/Winetricks/winetricks/issues/292
    w_call msls31
}

#----------------------------------------------------------------

# Problem - riched20 and riched30 both install riched20.dll!
# We may need a better way to distinguish between installed files.

w_metadata riched30 dlls \
    title="MS RichEdit Control 3.0 (riched20.dll, msls31.dll)" \
    publisher="Microsoft" \
    year="2001" \
    media="download" \
    file1="InstMsiA.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/riched20.dll" \
    installed_file2="$W_SYSTEM32_DLLS_WIN/msls31.dll"

load_riched30()
{
    # http://www.novell.com/documentation/nm1/readmeen_web/readmeen_web.html#Akx3j64
    # claims that Groupwise Messenger's View / Text Size command
    # only works with riched30, and recommends getting it by installing
    # msi 2, which just happens to come with riched30 version of riched20
    # (though not with a corresponding riched32, which might be a problem)

    # https://www.microsoft.com/en-us/download/details.aspx?id=21990
    # Originally at https://download.microsoft.com/download/WindowsInstaller/Install/2.0/W9XMe/EN-US/InstMsiA.exe
    # with sha256sum 536e4c8385d7d250fd5702a6868d1ed004692136eefad22252d0dac15f02563a
    # Mirror list at http://www.filewatcher.com/m/InstMsiA.Exe.1707856-0.html
    # But they all have a different sha256sum, 5ab8b82f578f09dbccf797754155e531b5996b532c1f19c531596ec07cc4b46d
    # Since mirrors are dead, going back to the microsoft.com version, via archive.org
    w_download ${W_DOWNLOADURLS}/InstMsiA.exe 536e4c8385d7d250fd5702a6868d1ed004692136eefad22252d0dac15f02563a

    w_try_cabextract --directory="$W_TMP" "$W_CACHE"/riched30/InstMsiA.exe
    w_try cp -f "$W_TMP"/riched20.dll "$W_SYSTEM32_DLLS"
    w_try cp -f "$W_TMP"/msls31.dll "$W_SYSTEM32_DLLS"
    w_override_dlls native,builtin riched20
}

#----------------------------------------------------------------

w_metadata richtx32 dlls \
    title="MS Rich TextBox Control 6.0" \
    publisher="Microsoft" \
    year="2012" \
    media="download" \
    file1="../vb6sp6/VB60SP6-KB2708437-x86-ENU.msi" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/richtx32.ocx"

load_richtx32()
{
    helper_vb6sp6 "$W_SYSTEM32_DLLS" richtx32.ocx
    w_try_regsvr richtx32.ocx
}

#----------------------------------------------------------------

w_metadata sdl dlls \
    title="Simple DirectMedia Layer" \
    publisher="Sam Lantinga" \
    year="2012" \
    media="download" \
    file1="SDL-1.2.15-win32.zip" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/SDL.dll"

load_sdl()
{
    # https://www.libsdl.org/download-1.2.php
    w_download ${W_DOWNLOADURLS}/SDL-1.2.15-win32.zip a28bbe38714ef7817b1c1e8082a48f391f15e4043402444b783952fca939edc1
    w_try_unzip "$W_SYSTEM32_DLLS" "$W_CACHE"/sdl/SDL-1.2.15-win32.zip SDL.dll
}

#----------------------------------------------------------------

w_metadata secur32 dlls \
    title="MS Security Support Provider Interface" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/secur32.dll"

load_secur32()
{
    w_warn "Installing native secur32 may lead to stack overflow crashes, see https://bugs.winehq.org/show_bug.cgi?id=45344"

    helper_win7sp1 x86_microsoft-windows-lsa_31bf3856ad364e35_6.1.7601.17514_none_a851f4adbb0d5141/secur32.dll
    w_try cp "$W_TMP/x86_microsoft-windows-lsa_31bf3856ad364e35_6.1.7601.17514_none_a851f4adbb0d5141/secur32.dll" "$W_SYSTEM32_DLLS/secur32.dll"

    if [ "$W_ARCH" = "win64" ]; then
        helper_win7sp1_x64 amd64_microsoft-windows-lsa_31bf3856ad364e35_6.1.7601.17514_none_04709031736ac277/secur32.dll
        w_try cp "$W_TMP/amd64_microsoft-windows-lsa_31bf3856ad364e35_6.1.7601.17514_none_04709031736ac277/secur32.dll" "$W_SYSTEM64_DLLS/secur32.dll"
    fi

    w_override_dlls native,builtin secur32
}

#----------------------------------------------------------------

w_metadata setupapi dlls \
    title="MS Setup API" \
    publisher="Microsoft" \
    year="2004" \
    media="download" \
    file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/setupapi.dll"

load_setupapi()
{
    helper_winxpsp3 i386/setupapi.dl_
    w_try_cabextract --directory="$W_SYSTEM32_DLLS" "$W_TMP"/i386/setupapi.dl_

    w_override_dlls native,builtin setupapi
}

#----------------------------------------------------------------

w_metadata shockwave dlls \
    title="Shockwave" \
    publisher="Adobe" \
    year="2018" \
    media="download" \
    file1="sw_lic_full_installer.msi" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/Adobe/Shockwave 12/shockwave_Projector_Loader.dcr"

load_shockwave() {
    # 2017/03/12: 39715a84b1d85347066fbf89a3af9f5e612b59402093b055cd423bd30a7f637d
    # 2017/03/15: 58f2152bf726d52f08fb41f904c62ff00fdf748c8ce413e8c8547da3a21922ba
    # 2017/08/03: bebebaef1644a994179a2e491ce3f55599d768f7c6019729f21e7029b1845b9c
    # 2017/12/12: 0a9813ac55a8718440518dc2f5f410a3a065b422fe0618c073bfc631b9abf12c
    # 2018/03/16: 4d7b408cf5b65a522b071d7d9ddbc5f6964911a7d55c418e31f393e6055cf796
    # 2018/05/24: 2b03fa11ff6f31b3fef9313264f0ef356ee11d5bc3642c30a2482b4ac5dd0084
    # 2018/06/14: a37f6c47b74fa3c96906e01b9b41d63c08d212fa3e357e354db1b5a93eb92c2f
    # 2019/04/02: 8e414c1a218157d2b83877fb0b6a5002c2e9bff4dc2a3095bae774a13e3e9dbf
    w_download ${W_DOWNLOADURLS}/sw_lic_full_installer.msi 8e414c1a218157d2b83877fb0b6a5002c2e9bff4dc2a3095bae774a13e3e9dbf

    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try "$WINE" msiexec /i sw_lic_full_installer.msi $W_UNATTENDED_SLASH_Q
}

#----------------------------------------------------------------

# While this is an sdk, some apps require it (those needing sapi.dll),
# so keeping in the dll category
w_metadata speechsdk dlls \
    title="MS Speech SDK 5.1" \
    publisher="Microsoft" \
    year="2009" \
    media="download" \
    file1="SpeechSDK51.exe" \
    installed_file1="$W_PROGRAMS_X86_WIN/Microsoft Speech SDK 5.1/Bin/SAPI51SampleApp.exe"

load_speechsdk()
{
    # https://www.microsoft.com/en-us/download/details.aspx?id=10121
    w_download ${W_DOWNLOADURLS}/SpeechSDK51.exe 520aa5d1a72dc6f41dc9b8b88603228ffd5d5d6f696224fc237ec4828fe7f6e0

    w_try_unzip "$W_TMP" "$W_CACHE"/speechsdk/SpeechSDK51.exe

    # Otherwise it only installs the SDK and not the redistributable:
    w_set_winver win2k

    # Only added in wine-2.18
    for stub in "$W_SYSTEM32_DLLS/Speech/Common/sapi.dll" "$W_SYSTEM64_DLLS/Speech/Common/sapi.dll"; do
        if [ -f "$stub" ]; then
            w_try rm "$stub"
        fi
    done

    w_try_cd "$W_TMP"
    w_try "$WINE" msiexec /i "Microsoft Speech SDK 5.1.msi" $W_UNATTENDED_SLASH_Q

    # If sapi.dll isn't in original location, applications won't start, see
    # e.g., https://bugs.winehq.org/show_bug.cgi?id=43841
    w_try ln -s "$W_COMMONFILES_X86/Microsoft Shared/Speech/sapi.dll" "$W_32BIT_DLLS/Speech/Common"

    w_override_dlls native sapi

    w_set_winver 'default'
}

#----------------------------------------------------------------

w_metadata tabctl32 dlls \
    title="Microsoft Tabbed Dialog Control 6.0 (tabctl32.ocx)" \
    publisher="Microsoft" \
    year="2012" \
    media="download" \
    file1="../vb6sp6/VB60SP6-KB2708437-x86-ENU.msi" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/tabctl32.ocx"

load_tabctl32()
{
    helper_vb6sp6 "$W_TMP" TabCtl32.ocx
    w_try mv "${W_TMP}/TabCtl32.ocx" "$W_SYSTEM32_DLLS/tabctl32.ocx"
    w_try_regsvr tabctl32.ocx
}

#----------------------------------------------------------------

w_metadata updspapi dlls \
    title="Windows Update Service API" \
    publisher="Microsoft" \
    year="2004" \
    media="download" \
    file1="../winxpsp3/WindowsXP-KB936929-SP3-x86-ENU.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/updspapi.dll"

load_updspapi()
{
    helper_winxpsp3 i386/update/updspapi.dll
    w_try cp -f "$W_TMP"/i386/update/updspapi.dll "$W_SYSTEM32_DLLS"

    w_override_dlls native,builtin updspapi
}

#----------------------------------------------------------------

w_metadata urlmon dlls \
    title="MS urlmon" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/urlmon.dll"

load_urlmon()
{
    helper_win7sp1 x86_microsoft-windows-i..ersandsecurityzones_31bf3856ad364e35_8.0.7601.17514_none_d1a4c8feac0dfcdb/urlmon.dll
    w_try cp "$W_TMP/x86_microsoft-windows-i..ersandsecurityzones_31bf3856ad364e35_8.0.7601.17514_none_d1a4c8feac0dfcdb/urlmon.dll" "$W_SYSTEM32_DLLS/urlmon.dll"

    if [ "$W_ARCH" = "win64" ]; then
        helper_win7sp1_x64 amd64_microsoft-windows-i..ersandsecurityzones_31bf3856ad364e35_8.0.7601.17514_none_2dc36482646b6e11/urlmon.dll
        w_try cp "$W_TMP/amd64_microsoft-windows-i..ersandsecurityzones_31bf3856ad364e35_8.0.7601.17514_none_2dc36482646b6e11/urlmon.dll" "$W_SYSTEM64_DLLS/urlmon.dll"
    fi

    w_override_dlls native,builtin urlmon

    w_call iertutil
}

#----------------------------------------------------------------

w_metadata usp10 dlls \
    title="Uniscribe" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/usp10.dll"

load_usp10()
{
    helper_win7sp1 x86_microsoft-windows-usp_31bf3856ad364e35_6.1.7601.17514_none_af01e2f9b6be7939/usp10.dll
    w_try cp "$W_TMP/x86_microsoft-windows-usp_31bf3856ad364e35_6.1.7601.17514_none_af01e2f9b6be7939/usp10.dll" "$W_SYSTEM32_DLLS/usp10.dll"

    if [ "$W_ARCH" = "win64" ]; then
        helper_win7sp1_x64 amd64_microsoft-windows-usp_31bf3856ad364e35_6.1.7601.17514_none_0b207e7d6f1bea6f/usp10.dll
        w_try cp "$W_TMP/amd64_microsoft-windows-usp_31bf3856ad364e35_6.1.7601.17514_none_0b207e7d6f1bea6f/usp10.dll" "$W_SYSTEM64_DLLS/usp10.dll"
    fi

    w_override_dlls native,builtin usp10
}

#----------------------------------------------------------------

w_metadata vb2run dlls \
    title="MS Visual Basic 2 runtime" \
    publisher="Microsoft" \
    year="1993" \
    media="download" \
    file1="VBRUN200.EXE" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/VBRUN200.DLL"

load_vb2run()
{
    # Not referenced on MS web anymore, but the old Microsoft Software Library FTP still has it.
    # See ftp://ftp.microsoft.com/Softlib/index.txt
    # 2014/05/31: Microsoft FTP is down ftp://$ftp_microsoft_com/Softlib/MSLFILES/VBRUN200.EXE
    # 2015/08/10: chatnfiles is down, conradshome.com is up (and has a LOT of old MS installers archived!)
    # 2018/11/15: now conradshome is down ,but quaddicted.com also has it (and a lot more)
    w_download ${W_DOWNLOADURLS}/VBRUN200.EXE 4b0811d8fdcac1fd9411786c9119dc8d98d0540948211bdbc1ac682fbe5c0228
    w_try_unzip "$W_TMP" "$W_CACHE"/vb2run/VBRUN200.EXE
    w_try cp -f "$W_TMP/VBRUN200.DLL" "$W_SYSTEM32_DLLS"
}

#----------------------------------------------------------------

w_metadata vb3run dlls \
    title="MS Visual Basic 3 runtime" \
    publisher="Microsoft" \
    year="1998" \
    media="download" \
    file1="vb3run.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/Vbrun300.dll"

load_vb3run()
{
    # See https://support.microsoft.com/kb/196285
    w_download ${W_DOWNLOADURLS}/vb3run.exe 3ca3ad6332f83b5c2b86e4758afa400150f07ae66ce8b850d8f9d6bcd47ad4cd
    w_try_unzip "$W_TMP" "$W_CACHE"/vb3run/vb3run.exe
    w_try cp -f "$W_TMP/Vbrun300.dll" "$W_SYSTEM32_DLLS"
}

#----------------------------------------------------------------

w_metadata vb4run dlls \
    title="MS Visual Basic 4 runtime" \
    publisher="Microsoft" \
    year="1998" \
    media="download" \
    file1="vb4run.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/Vb40032.dll"

load_vb4run()
{
    # See https://support.microsoft.com/kb/196286
    w_download ${W_DOWNLOADURLS}/vb4run.exe 40931308b5a137f9ce3e9da9b43f4ca6688e18b523687cfea8be6cdffa3153fb
    w_try_unzip "$W_TMP" "$W_CACHE"/vb4run/vb4run.exe
    w_try cp -f "$W_TMP/Vb40032.dll" "$W_SYSTEM32_DLLS"
    w_try cp -f "$W_TMP/Vb40016.dll" "$W_SYSTEM32_DLLS"
}

#----------------------------------------------------------------

w_metadata vb5run dlls \
    title="MS Visual Basic 5 runtime" \
    publisher="Microsoft" \
    year="2001" \
    media="download" \
    file1="msvbvm50.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/msvbvm50.dll"

load_vb5run()
{
    w_download ${W_DOWNLOADURLS}/msvbvm50.exe b5f8ea5b9d8b30822a2be2cdcb89cda99ec0149832659ad81f45360daa6e6965
    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try "$WINE" msvbvm50.exe $W_UNATTENDED_SLASH_Q
}

#----------------------------------------------------------------

w_metadata vb6run dlls \
    title="MS Visual Basic 6 runtime sp6" \
    publisher="Microsoft" \
    year="2004" \
    media="download" \
    file1="vbrun60sp6.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/MSVBVM60.DLL"

load_vb6run()
{
    # https://support.microsoft.com/kb/290887
    if test ! -f "$W_CACHE"/vb6run/vbrun60sp6.exe; then
        w_download ${W_DOWNLOADURLS}/VB6.0-KB290887-X86.exe 467b5a10c369865f2021d379fc0933cb382146b702bbca4bcb703fc86f4322bb

        w_try "$WINE" "$W_CACHE"/vb6run/VB6.0-KB290887-X86.exe "/T:$W_TMP_WIN" /c $W_UNATTENDED_SLASH_Q
        if test ! -f "$W_TMP"/vbrun60sp6.exe; then
            w_die vbrun60sp6.exe not found
        fi
        w_try mv "$W_TMP"/vbrun60sp6.exe "$W_CACHE"/vb6run
    fi

    # Delete some fake DLLs to ensure that the installer overwrites them.
    rm -f "$W_SYSTEM32_DLLS"/comcat.dll
    rm -f "$W_SYSTEM32_DLLS"/oleaut32.dll
    rm -f "$W_SYSTEM32_DLLS"/olepro32.dll
    rm -f "$W_SYSTEM32_DLLS"/stdole2.tlb

    w_try_cd "$W_CACHE/$W_PACKAGE"
    # Exits with status 43 for some reason?
    "$WINE" vbrun60sp6.exe $W_UNATTENDED_SLASH_Q

    status=$?
    case $status in
        0|43) ;;
        *) w_die "$W_PACKAGE installation failed"
    esac
}

#----------------------------------------------------------------

winetricks_vcrun6_helper() {
    if test ! -f "$W_CACHE"/vcrun6/vcredist.exe; then
        w_download_to vcrun6 ${W_DOWNLOADURLS}/VC6RedistSetup_deu.exe c2eb91d9c4448d50e46a32fecbcc3b418706d002beab9b5f4981de552098cee7

        w_try "$WINE" "$W_CACHE"/vcrun6/vc6redistsetup_deu.exe "/T:$W_TMP_WIN" /c $W_UNATTENDED_SLASH_Q
        if test ! -f "$W_TMP"/vcredist.exe; then
            w_die vcredist.exe not found
        fi
        mv "$W_TMP"/vcredist.exe "$W_CACHE"/vcrun6
    fi
}

w_metadata vcrun6 dlls \
    title="Visual C++ 6 SP4 libraries (mfc42, msvcp60, msvcirt)" \
    publisher="Microsoft" \
    year="2000" \
    media="download" \
    file1="vc6redistsetup_deu.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/mfc42.dll"

load_vcrun6()
{
    # Load the Visual C++ 6 runtime libraries, including the elusive mfc42u.dll
    winetricks_vcrun6_helper

    # Delete some fake DLLs to avoid vcredist installer warnings
    rm -f "$W_SYSTEM32_DLLS"/comcat.dll
    rm -f "$W_SYSTEM32_DLLS"/msvcrt.dll
    rm -f "$W_SYSTEM32_DLLS"/oleaut32.dll
    rm -f "$W_SYSTEM32_DLLS"/olepro32.dll
    rm -f "$W_SYSTEM32_DLLS"/stdole2.tlb
    "$WINE" "$W_CACHE"/vcrun6/vcredist.exe

    status=$?
    case $status in
        0|43) ;;
        *) w_die vcrun6 installation failed
    esac

    # And then some apps need mfc42u.dll, dunno what the right way
    # is to get it, vcredist doesn't seem to install it by default?
    load_mfc42
}

w_metadata mfc42 dlls \
    title="Visual C++ 6 SP4 mfc42 library; part of vcrun6" \
    publisher="Microsoft" \
    year="2000" \
    media="download" \
    file1="../vcrun6/vc6redistsetup_deu.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/mfc42u.dll"

load_mfc42()
{
    winetricks_vcrun6_helper

    w_try_cabextract "$W_CACHE"/vcrun6/vcredist.exe -d "$W_SYSTEM32_DLLS" -F "mfc42*.dll"
}

w_metadata msvcirt dlls \
    title="Visual C++ 6 SP4 msvcirt library; part of vcrun6" \
    publisher="Microsoft" \
    year="2000" \
    media="download" \
    file1="../vcrun6/vc6redistsetup_deu.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/msvcirt.dll"

load_msvcirt()
{
    winetricks_vcrun6_helper

    w_try_cabextract "$W_CACHE"/vcrun6/vcredist.exe -d "$W_SYSTEM32_DLLS" -F msvcirt.dll
}

#----------------------------------------------------------------

# FIXME: we don't currently have an install check that can distinguish
# between SP4 and SP6, it would have to check size or version of a file,
# or maybe a registry key.

w_metadata vcrun6sp6 dlls \
    title="Visual C++ 6 SP6 libraries (with fixes in ATL and MFC)" \
    publisher="Microsoft" \
    year="2004" \
    media="download" \
    file1="Vs6sp6.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/mfc42.dll"

load_vcrun6sp6()
{
    w_download ${W_DOWNLOADURLS}/Vs6sp6.exe 7fa1d1778824b55a5fceb02f45c399b5d4e4dce7403661e67e587b5f455edbf3

    # No EULA is presented when passing command-line extraction arguments,
    # so we'll simplify extraction with cabextract.
    w_try_cabextract "$W_CACHE"/vcrun6sp6/Vs6sp6.exe -d "$W_TMP" -F vcredist.exe
    w_try_cd "$W_TMP"

    # Delete some fake DLLs to avoid vcredist installer warnings
    w_try rm -f "$W_SYSTEM32_DLLS"/comcat.dll
    w_try rm -f "$W_SYSTEM32_DLLS"/msvcrt.dll
    w_try rm -f "$W_SYSTEM32_DLLS"/oleaut32.dll
    w_try rm -f "$W_SYSTEM32_DLLS"/olepro32.dll
    w_try rm -f "$W_SYSTEM32_DLLS"/stdole2.tlb
    # vcredist still exits with status 43.  Anyone know why?
    "$WINE" vcredist.exe

    status=$?
    case $status in
        0|43) ;;
        *) w_die "$W_PACKAGE installation failed"
    esac

    # And then some apps need mfc42u.dll, dont know what right way
    # is to get it, vcredist doesn't install it by default?
    w_try_cabextract vcredist.exe -d "$W_SYSTEM32_DLLS" -F mfc42u.dll
    # Should the mfc42 verb install this one instead?
}

#----------------------------------------------------------------

w_metadata vcrun2003 dlls \
    title="Visual C++ 2003 libraries (mfc71,msvcp71,msvcr71)" \
    publisher="Microsoft" \
    year="2003" \
    media="download" \
    file1="BZEditW32_1.6.5.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/msvcp71.dll"

load_vcrun2003()
{
    # Load the Visual C++ 2003 runtime libraries
    # Sadly, I know of no Microsoft URL for these
    echo "Installing BZFlag (which comes with the Visual C++ 2003 runtimes)"
    # winetricks-test can't handle ${file1} in url since it does a raw parsing :/
    w_download ${W_DOWNLOADURLS}/BZEditW32_1.6.5.exe 84d1bda5dbf814742898a2e1c0e4bc793e9bc1fba4b7a93d59a7ef12bd0fd802
    w_try "$WINE" "$W_CACHE/vcrun2003/${file1}" $W_UNATTENDED_SLASH_S
    w_try cp "$W_PROGRAMS_X86_UNIX/BZEdit1.6.5"/m*71* "$W_SYSTEM32_DLLS"
}

#----------------------------------------------------------------

# Temporary fix for bug 169
# The | symbol in installed_file1 means "or".
# (Adding an installed_file2 would mean 'and'.)
# Perhaps we should test for one if winxp mode, and the other if win7 mode;
# if that becomes important to get right, we'll do something like
# "if installed_file1 is just the single char @, call test_installed_$verb"
# and then define that function here.
w_metadata vcrun2005 dlls \
    title="Visual C++ 2005 libraries (mfc80,msvcp80,msvcr80)" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="vcredist_x86.EXE" \
    installed_file1="c:/windows/winsxs/x86_Microsoft.VC80.MFC_1fc8b3b9a1e18e3b_8.0.50727.6195_x-ww_150c9e8b/mfc80.dll|c:/windows/winsxs/x86_microsoft.vc80.mfc_1fc8b3b9a1e18e3b_8.0.50727.6195_none_deadbeef/mfc80.dll"

load_vcrun2005()
{
    # 2011/06: Security update, see
    # https://technet.microsoft.com/library/security/ms11-025 or
    # https://support.microsoft.com/kb/2538242
    w_download ${W_DOWNLOADURLS}/vcrun2005/vcredist_x86.EXE 4ee4da0fe62d5fa1b5e80c6e6d88a4a2f8b3b140c35da51053d0d7b72a381d29

    # For native to be used, msvc* dlls must either be set to native only, OR
    # set to native, builtin and remove wine's builtin manifest. Setting to native only breaks several apps,
    # e.g., Dirac Codec and Ragnarok Online.
    # For more info, see:
    # https://bugs.winehq.org/show_bug.cgi?id=28225
    # https://bugs.winehq.org/show_bug.cgi?id=33604
    # https://bugs.winehq.org/show_bug.cgi?id=42859
    w_override_dlls native,builtin atl80 msvcm80 msvcp80 msvcr80 vcomp

    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try "$WINE" "$file1" $W_UNATTENDED_SLASH_Q

    if [ $W_ARCH = win64 ] ;then
        w_download ${W_DOWNLOADURLS}/vcrun2005/vcredist_x64.EXE 0551a61c85b718e1fa015b0c3e3f4c4eea0637055536c00e7969286b4fa663e0
        w_try "$WINE" vcredist_x64.exe $W_UNATTENDED_SLASH_Q
    fi
}

#----------------------------------------------------------------

w_metadata vcrun2008 dlls \
    title="Visual C++ 2008 libraries (mfc90,msvcp90,msvcr90)" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="vcredist_x86.exe" \
    installed_file1="$W_PROGRAMS_X86_WIN/Common Files/Microsoft Shared/VC/msdia90.dll"

load_vcrun2008()
{
    # June 2011 security update, see
    # https://technet.microsoft.com/library/security/ms11-025 or
    # https://support.microsoft.com/kb/2538242
    w_download ${W_DOWNLOADURLS}/vcrun2008/vcredist_x86.exe 6b3e4c51c6c0e5f68c8a72b497445af3dbf976394cbb62aa23569065c28deeb6

    # For native to be used, msvc* dlls must either be set to native only, OR
    # set to native, builtin and remove wine's builtin manifest. Setting to native only breaks several apps,
    # e.g., Dirac Codec and Ragnarok Online.
    # For more info, see:
    # https://bugs.winehq.org/show_bug.cgi?id=28225
    # https://bugs.winehq.org/show_bug.cgi?id=33604
    # https://bugs.winehq.org/show_bug.cgi?id=42859
    w_override_dlls native,builtin atl90 msvcm90 msvcp90 msvcr90 vcomp90

    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try "$WINE" "$file1" $W_UNATTENDED_SLASH_Q

    case "$W_ARCH" in
        win64)
            # Also install the 64-bit version
            # 2016/11/15: b811f2c047a3e828517c234bd4aa4883e1ec591d88fad21289ae68a6915a6665
            w_download ${W_DOWNLOADURLS}/vcrun2008/vcredist_x64.exe b811f2c047a3e828517c234bd4aa4883e1ec591d88fad21289ae68a6915a6665
            if w_workaround_wine_bug 30713 "Manually extracting the 64-bit dlls" ,3.8; then
                rm -f "$W_TMP"/*  # Avoid permission error
                w_try_cabextract --directory="$W_TMP" vcredist_x64.exe
                w_try_cabextract --directory="$W_TMP" "$W_TMP/vc_red.cab"

                w_try cp "$W_TMP"/atl90.dll.30729.6161.Microsoft_VC90_ATL_x64.QFE "$W_SYSTEM64_DLLS"/atl90.dll
                w_try cp "$W_TMP"/mfc90.dll.30729.6161.Microsoft_VC90_MFC_x64.QFE "$W_SYSTEM64_DLLS"/mfc90.dll
                w_try cp "$W_TMP"/mfcm90.dll.30729.6161.Microsoft_VC90_MFC_x64.QFE "$W_SYSTEM64_DLLS"/mfcm90.dll
                w_try cp "$W_TMP"/msvcm90.dll.30729.6161.Microsoft_VC90_CRT_x64.QFE "$W_SYSTEM64_DLLS"/msvcm90.dll
                w_try cp "$W_TMP"/msvcp90.dll.30729.6161.Microsoft_VC90_CRT_x64.QFE "$W_SYSTEM64_DLLS"/msvcp90.dll
                w_try cp "$W_TMP"/msvcr90.dll.30729.6161.Microsoft_VC90_CRT_x64.QFE "$W_SYSTEM64_DLLS"/msvcr90.dll
                w_try cp "$W_TMP"/vcomp90.dll.30729.6161.Microsoft_VC90_OpenMP_x64.QFE "$W_SYSTEM64_DLLS"/vcomp90.dll
            else
                w_try "$WINE" vcredist_x64.exe $W_UNATTENDED_SLASH_Q
            fi
            ;;
    esac
}

#----------------------------------------------------------------

w_metadata vcrun2010 dlls \
    title="Visual C++ 2010 libraries (mfc100,msvcp100,msvcr100)" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="vcredist_x86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/mfc100.dll"

load_vcrun2010()
{
    # See https://www.microsoft.com/en-us/download/details.aspx?id=5555
    w_download ${W_DOWNLOADURLS}/vcrun2010/vcredist_x86.exe 8162b2d665ca52884507ede19549e99939ce4ea4a638c537fa653539819138c8

    w_override_dlls native,builtin msvcp100 msvcr100 vcomp100 atl100
    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try "$WINE" vcredist_x86.exe $W_UNATTENDED_SLASH_Q

    case "$W_ARCH" in
        win64)
            # Also install the 64-bit version
            # https://www.microsoft.com/en-us/download/details.aspx?id=13523
            w_download ${W_DOWNLOADURLS}/vcrun2010/vcredist_x64.exe c6cd2d3f0b11dc2a604ffdc4dd97861a83b77e21709ba71b962a47759c93f4c8
            if w_workaround_wine_bug 30713 "Manually extracting the 64-bit dlls" ,3.8; then
                w_try_cabextract --directory="$W_TMP" vcredist_x64.exe -F '*.cab'
                w_try_cabextract --directory="$W_TMP" "$W_TMP"/vc_red.cab
                cp "$W_TMP"/F_CENTRAL_mfc100_x64 "$W_SYSTEM64_DLLS"/mfc100.dll
                cp "$W_TMP"/F_CENTRAL_mfc100u_x64 "$W_SYSTEM64_DLLS"/mfc100u.dll
                cp "$W_TMP"/F_CENTRAL_msvcr100_x64 "$W_SYSTEM64_DLLS"/msvcr100.dll
                cp "$W_TMP"/F_CENTRAL_msvcp100_x64 "$W_SYSTEM64_DLLS"/msvcp100.dll
                cp "$W_TMP"/F_CENTRAL_vcomp100_x64 "$W_SYSTEM64_DLLS"/vcomp100.dll
                cp "$W_TMP"/F_CENTRAL_atl100_x64 "$W_SYSTEM64_DLLS"/atl100.dll
            else
                w_try "$WINE" vcredist_x64.exe $W_UNATTENDED_SLASH_Q
            fi
            ;;
    esac
}

#----------------------------------------------------------------

w_metadata vcrun2012 dlls \
    title="Visual C++ 2012 libraries (atl110,mfc110,mfc110u,msvcp110,msvcr110,vcomp110)" \
    publisher="Microsoft" \
    year="2012" \
    media="download" \
    file1="vcredist_x86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/mfc110.dll"

load_vcrun2012()
{
    # https://www.microsoft.com/en-us/download/details.aspx?id=30679
    w_download ${W_DOWNLOADURLS}/vcrun2012/vcredist_x86.exe b924ad8062eaf4e70437c8be50fa612162795ff0839479546ce907ffa8d6e386

    w_override_dlls native,builtin atl110 msvcp110 msvcr110 vcomp110
    w_try_cd "$W_CACHE"/"$W_PACKAGE"
    w_try "$WINE" vcredist_x86.exe $W_UNATTENDED_SLASH_Q

    case "$W_ARCH" in
        win64)
            # Also install the 64-bit version
            # 2015/10/19: 681be3e5ba9fd3da02c09d7e565adfa078640ed66a0d58583efad2c1e3cc4064
            w_download ${W_DOWNLOADURLS}/vcrun2012/vcredist_x64.exe 681be3e5ba9fd3da02c09d7e565adfa078640ed66a0d58583efad2c1e3cc4064
            if w_workaround_wine_bug 30713 "Manually extracting the 64-bit dlls" ,3.8; then
                rm -f "$W_TMP"/*  # Avoid permission error
                w_try_cabextract --directory="$W_TMP" vcredist_x64.exe
                w_try_cabextract --directory="$W_TMP" "$W_TMP/a2"
                w_try_cabextract --directory="$W_TMP" "$W_TMP/a3"
                cp "$W_TMP"/F_CENTRAL_atl110_x64 "$W_SYSTEM64_DLLS"/atl110.dll
                cp "$W_TMP"/F_CENTRAL_mfc110_x64 "$W_SYSTEM64_DLLS"/mfc110.dll
                cp "$W_TMP"/F_CENTRAL_mfc110u_x64 "$W_SYSTEM64_DLLS"/mfc110u.dll
                cp "$W_TMP"/F_CENTRAL_msvcp110_x64 "$W_SYSTEM64_DLLS"/msvcp110.dll
                cp "$W_TMP"/F_CENTRAL_msvcr110_x64 "$W_SYSTEM64_DLLS"/msvcr110.dll
                cp "$W_TMP"/F_CENTRAL_vcomp110_x64 "$W_SYSTEM64_DLLS"/vcomp110.dll
            else
                w_try "$WINE" vcredist_x64.exe $W_UNATTENDED_SLASH_Q
            fi
            ;;
    esac
}

#----------------------------------------------------------------

w_metadata vcrun2013 dlls \
    title="Visual C++ 2013 libraries (mfc120,mfc120u,msvcp120,msvcr120,vcomp120)" \
    publisher="Microsoft" \
    year="2013" \
    media="download" \
    file1="vcredist_x86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/mfc120.dll"

load_vcrun2013()
{
    # https://support.microsoft.com/en-gb/help/3179560/update-for-visual-c-2013-and-visual-c-redistributable-package
    # 2015/01/14: a22895e55b26202eae166838edbe2ea6aad00d7ea600c11f8a31ede5cbce2048
    # 2019/03/24: 89f4e593ea5541d1c53f983923124f9fd061a1c0c967339109e375c661573c17
    w_download ${W_DOWNLOADURLS}/vcrun2013/vcredist_x86.exe 89f4e593ea5541d1c53f983923124f9fd061a1c0c967339109e375c661573c17

    w_override_dlls native,builtin atl120 msvcp120 msvcr120 vcomp120
    w_try_cd "$W_CACHE"/"$W_PACKAGE"
    w_try "$WINE" vcredist_x86.exe $W_UNATTENDED_SLASH_Q

    case "$W_ARCH" in
        win64)
            # Also install the 64-bit version
            # 2015/10/19: e554425243e3e8ca1cd5fe550db41e6fa58a007c74fad400274b128452f38fb8
            # 2019/03/24: 20e2645b7cd5873b1fa3462b99a665ac8d6e14aae83ded9d875fea35ffdd7d7e
            w_download ${W_DOWNLOADURLS}/vcrun2013/vcredist_x64.exe 20e2645b7cd5873b1fa3462b99a665ac8d6e14aae83ded9d875fea35ffdd7d7e
            if w_workaround_wine_bug 30713 "Manually extracting the 64-bit dlls" ,3.8; then
                rm -f "$W_TMP"/*  # Avoid permission error
                w_try_cabextract --directory="$W_TMP" vcredist_x64.exe
                w_try_cabextract --directory="$W_TMP" "$W_TMP/a2"
                w_try_cabextract --directory="$W_TMP" "$W_TMP/a3"
                cp "$W_TMP"/F_CENTRAL_mfc120_x64 "$W_SYSTEM64_DLLS"/mfc120.dll
                cp "$W_TMP"/F_CENTRAL_mfc120u_x64 "$W_SYSTEM64_DLLS"/mfc120u.dll
                cp "$W_TMP"/F_CENTRAL_msvcp120_x64 "$W_SYSTEM64_DLLS"/msvcp120.dll
                cp "$W_TMP"/F_CENTRAL_msvcr120_x64 "$W_SYSTEM64_DLLS"/msvcr120.dll
                cp "$W_TMP"/F_CENTRAL_vcomp120_x64 "$W_SYSTEM64_DLLS"/vcomp120.dll
            else
                w_try "$WINE" vcredist_x64.exe $W_UNATTENDED_SLASH_Q
            fi
            ;;
    esac
}

#----------------------------------------------------------------

w_metadata vcrun2015 dlls \
    title="Visual C++ 2015 libraries (concrt140.dll,mfc140.dll,mfc140u.dll,mfcm140.dll,mfcm140u.dll,msvcp140.dll,vcamp140.dll,vccorlib140.dll,vcomp140.dll,vcruntime140.dll)" \
    publisher="Microsoft" \
    year="2015" \
    media="download" \
    conflicts="vcrun2017 vcrun2019" \
    file1="vc_redist.x86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/mfc140.dll"

load_vcrun2015()
{
    # https://www.microsoft.com/en-us/download/details.aspx?id=48145
    # 2015/10/12: fdd1e1f0dcae2d0aa0720895eff33b927d13076e64464bb7c7e5843b7667cd14
    w_download ${W_DOWNLOADURLS}/vcrun2015/vc_redist.x86.exe fdd1e1f0dcae2d0aa0720895eff33b927d13076e64464bb7c7e5843b7667cd14

    if w_workaround_wine_bug 37781; then
        w_warn "This may fail in non-XP mode, see https://bugs.winehq.org/show_bug.cgi?id=37781"
    fi

    w_override_dlls native,builtin api-ms-win-crt-private-l1-1-0 api-ms-win-crt-conio-l1-1-0 api-ms-win-crt-heap-l1-1-0 api-ms-win-crt-locale-l1-1-0 api-ms-win-crt-math-l1-1-0 api-ms-win-crt-runtime-l1-1-0 api-ms-win-crt-stdio-l1-1-0 api-ms-win-crt-time-l1-1-0 atl140 concrt140 msvcp140 msvcr140 ucrtbase vcomp140 vcruntime140

    w_set_winver winxp

    w_try_cd "$W_CACHE"/"$W_PACKAGE"
    w_try "$WINE" vc_redist.x86.exe $W_UNATTENDED_SLASH_Q

    case "$W_ARCH" in
        win64)
            # Also install the 64-bit version
            # 2015/10/12: 5eea714e1f22f1875c1cb7b1738b0c0b1f02aec5ecb95f0fdb1c5171c6cd93a3
            w_download ${W_DOWNLOADURLS}/vcrun2015/vc_redist.x64.exe 5eea714e1f22f1875c1cb7b1738b0c0b1f02aec5ecb95f0fdb1c5171c6cd93a3
            if w_workaround_wine_bug 30713 "Manually extracting the 64-bit dlls", 3.8; then
                rm -f "$W_TMP"/*  # Avoid permission error
                w_try_cabextract --directory="$W_TMP" vc_redist.x64.exe
                w_try_cabextract --directory="$W_TMP" "$W_TMP/a10"
                w_try_cabextract --directory="$W_TMP" "$W_TMP/a11"
                cp "$W_TMP"/concrt140.dll "$W_SYSTEM64_DLLS"/concrt140.dll
                cp "$W_TMP"/mfc140.dll "$W_SYSTEM64_DLLS"/mfc140.dll
                cp "$W_TMP"/mfc140u.dll "$W_SYSTEM64_DLLS"/mfc140u.dll
                cp "$W_TMP"/mfcm140.dll "$W_SYSTEM64_DLLS"/mfcm140.dll
                cp "$W_TMP"/mfcm140u.dll "$W_SYSTEM64_DLLS"/mfcm140u.dll
                cp "$W_TMP"/msvcp140.dll "$W_SYSTEM64_DLLS"/msvcp140.dll
                cp "$W_TMP"/vcamp140.dll "$W_SYSTEM64_DLLS"/vcamp140.dll
                cp "$W_TMP"/vccorlib140.dll "$W_SYSTEM64_DLLS"/vccorlib140.dll
                cp "$W_TMP"/vcomp140.dll "$W_SYSTEM64_DLLS"/vcomp140.dll
                cp "$W_TMP"/vcruntime140.dll "$W_SYSTEM64_DLLS"/vcruntime140.dll

                cp "$W_TMP"/api_ms_win_crt_conio_l1_1_0.dll "$W_SYSTEM64_DLLS"/api-ms-win-crt-conio-l1-1-0.dll
                cp "$W_TMP"/api_ms_win_crt_heap_l1_1_0.dll "$W_SYSTEM64_DLLS"/api-ms-win-crt-heap-l1-1-0.dll
                cp "$W_TMP"/api_ms_win_crt_locale_l1_1_0.dll "$W_SYSTEM64_DLLS"/api-ms-win-crt-locale-l1-1-0.dll
                cp "$W_TMP"/api_ms_win_crt_math_l1_1_0.dll "$W_SYSTEM64_DLLS"/api-ms-win-crt-math-l1-1-0.dll
                cp "$W_TMP"/api_ms_win_crt_runtime_l1_1_0.dll "$W_SYSTEM64_DLLS"/api-ms-win-crt-runtime-l1-1-0.dll
                cp "$W_TMP"/api_ms_win_crt_stdio_l1_1_0.dll "$W_SYSTEM64_DLLS"/api-ms-win-crt-stdio-l1-1-0.dll
                cp "$W_TMP"/ucrtbase.dll "$W_SYSTEM64_DLLS"/ucrtbase.dll
            else
                w_try "$WINE" vc_redist.x64.exe $W_UNATTENDED_SLASH_Q
            fi
            ;;
    esac
}

#----------------------------------------------------------------

w_metadata vcrun2017 dlls \
    title="Visual C++ 2017 libraries (concrt140.dll,mfc140.dll,mfc140u.dll,mfcm140.dll,mfcm140u.dll,msvcp140.dll,vcamp140.dll,vccorlib140.dll,vcomp140.dll,vcruntime140.dll)" \
    publisher="Microsoft" \
    year="2017" \
    media="download" \
    conflicts="vcrun2015 vcrun2019" \
    file1="vc_redist.x86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/mfc140.dll"

load_vcrun2017()
{
    # https://support.microsoft.com/en-gb/help/2977003/the-latest-supported-visual-c-downloads
    # 2017/10/02: 2da11e22a276be85970eaed255daf3d92af84e94142ec04252326a882e57303e
    # 2019/03/17: 7355962b95d6a5441c304cd2b86baf37bc206f63349f4a02289bcfb69ef142d3
    # 2019/08/14: 54ad46ae80984aa48cae6361213692c96b3639e322730d28c7fb93b183c761da
    w_download ${W_DOWNLOADURLS}/vcrun2017/vc_redist.x86.exe 54ad46ae80984aa48cae6361213692c96b3639e322730d28c7fb93b183c761da

    if w_workaround_wine_bug 37781; then
        w_warn "This may fail in non-XP mode, see https://bugs.winehq.org/show_bug.cgi?id=37781"
    fi

    w_override_dlls native,builtin api-ms-win-crt-private-l1-1-0 api-ms-win-crt-conio-l1-1-0 api-ms-win-crt-heap-l1-1-0 api-ms-win-crt-locale-l1-1-0 api-ms-win-crt-math-l1-1-0 api-ms-win-crt-runtime-l1-1-0 api-ms-win-crt-stdio-l1-1-0 api-ms-win-crt-time-l1-1-0 atl140 concrt140 msvcp140 msvcr140 ucrtbase vcomp140 vcruntime140

    w_set_winver winxp

    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try "$WINE" vc_redist.x86.exe $W_UNATTENDED_SLASH_Q

    case "$W_ARCH" in
        win64)
            # Also install the 64-bit version
            # https://support.microsoft.com/en-gb/help/2977003/the-latest-supported-visual-c-downloads
            # 2017/10/02: 7434bf559290cccc3dd3624f10c9e6422cce9927d2231d294114b2f929f0e465
            # 2019/03/17: b192e143d55257a0a2f76be42e44ff8ee14014f3b1b196c6e59829b6b3ec453c
            # 2019/08/14: 5b0cbb977f2f5253b1ebe5c9d30edbda35dbd68fb70de7af5faac6423db575b5
            w_download ${W_DOWNLOADURLS}/vcrun2017/vc_redist.x64.exe 5b0cbb977f2f5253b1ebe5c9d30edbda35dbd68fb70de7af5faac6423db575b5
            if w_workaround_wine_bug 30713 "Manually extracting the 64-bit dlls" ,3.8; then
                rm -f "$W_TMP"/*  # Avoid permission error
                w_try_cabextract --directory="$W_TMP" vc_redist.x64.exe
                w_try_cabextract --directory="$W_TMP" "$W_TMP/a10"
                w_try_cabextract --directory="$W_TMP" "$W_TMP/a11"
                cp "$W_TMP"/concrt140.dll "$W_SYSTEM64_DLLS"/concrt140.dll
                cp "$W_TMP"/mfc140.dll "$W_SYSTEM64_DLLS"/mfc140.dll
                cp "$W_TMP"/mfc140u.dll "$W_SYSTEM64_DLLS"/mfc140u.dll
                cp "$W_TMP"/mfcm140.dll "$W_SYSTEM64_DLLS"/mfcm140.dll
                cp "$W_TMP"/mfcm140u.dll "$W_SYSTEM64_DLLS"/mfcm140u.dll
                cp "$W_TMP"/msvcp140.dll "$W_SYSTEM64_DLLS"/msvcp140.dll
                cp "$W_TMP"/vcamp140.dll "$W_SYSTEM64_DLLS"/vcamp140.dll
                cp "$W_TMP"/vccorlib140.dll "$W_SYSTEM64_DLLS"/vccorlib140.dll
                cp "$W_TMP"/vcomp140.dll "$W_SYSTEM64_DLLS"/vcomp140.dll
                cp "$W_TMP"/vcruntime140.dll "$W_SYSTEM64_DLLS"/vcruntime140.dll

                cp "$W_TMP"/api_ms_win_crt_conio_l1_1_0.dll "$W_SYSTEM64_DLLS"/api-ms-win-crt-conio-l1-1-0.dll
                cp "$W_TMP"/api_ms_win_crt_heap_l1_1_0.dll "$W_SYSTEM64_DLLS"/api-ms-win-crt-heap-l1-1-0.dll
                cp "$W_TMP"/api_ms_win_crt_locale_l1_1_0.dll "$W_SYSTEM64_DLLS"/api-ms-win-crt-locale-l1-1-0.dll
                cp "$W_TMP"/api_ms_win_crt_math_l1_1_0.dll "$W_SYSTEM64_DLLS"/api-ms-win-crt-math-l1-1-0.dll
                cp "$W_TMP"/api_ms_win_crt_runtime_l1_1_0.dll "$W_SYSTEM64_DLLS"/api-ms-win-crt-runtime-l1-1-0.dll
                cp "$W_TMP"/api_ms_win_crt_stdio_l1_1_0.dll "$W_SYSTEM64_DLLS"/api-ms-win-crt-stdio-l1-1-0.dll
                cp "$W_TMP"/ucrtbase.dll "$W_SYSTEM64_DLLS"/ucrtbase.dll
            else
                w_try "$WINE" vc_redist.x64.exe $W_UNATTENDED_SLASH_Q
            fi
            ;;
    esac
}

#----------------------------------------------------------------

w_metadata vcrun2019 dlls \
    title="Visual C++ 2015-2019 libraries (concrt140.dll,mfc140.dll,mfc140u.dll,mfcm140.dll,mfcm140u.dll,msvcp140.dll,vcamp140.dll,vccorlib140.dll,vcomp140.dll,vcruntime140.dll)" \
    publisher="Microsoft" \
    year="2019" \
    media="download" \
    conflicts="vcrun2015 vcrun2017" \
    file1="vc_redist.x86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/mfc140.dll"

load_vcrun2019()
{
    # https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads
    # 2019/12/26: e59ae3e886bd4571a811fe31a47959ae5c40d87c583f786816c60440252cd7ec
    # 2020/03/23: ac96016f1511ae3eb5ec9de04551146fe351b7f97858dcd67163912e2302f5d6
    w_download ${W_DOWNLOADURLS}/vcrun2019/vc_redist.x86.exe ac96016f1511ae3eb5ec9de04551146fe351b7f97858dcd67163912e2302f5d6

    w_override_dlls native,builtin api-ms-win-crt-private-l1-1-0 api-ms-win-crt-conio-l1-1-0 api-ms-win-crt-heap-l1-1-0 api-ms-win-crt-locale-l1-1-0 api-ms-win-crt-math-l1-1-0 api-ms-win-crt-runtime-l1-1-0 api-ms-win-crt-stdio-l1-1-0 api-ms-win-crt-time-l1-1-0 atl140 concrt140 msvcp140 msvcr140 ucrtbase vcomp140 vcruntime140

    w_try_cd "$W_CACHE"/"$W_PACKAGE"
    w_try "$WINE" vc_redist.x86.exe $W_UNATTENDED_SLASH_Q

    case "$W_ARCH" in
        win64)
            # Also install the 64-bit version
            # 2019/12/26: 40ea2955391c9eae3e35619c4c24b5aaf3d17aeaa6d09424ee9672aa9372aeed
            # 2020/03/23: b6c82087a2c443db859fdbeaae7f46244d06c3f2a7f71c35e50358066253de52
            w_download ${W_DOWNLOADURLS}/vcrun2019/vc_redist.x64.exe b6c82087a2c443db859fdbeaae7f46244d06c3f2a7f71c35e50358066253de52
            w_try "$WINE" vc_redist.x64.exe $W_UNATTENDED_SLASH_Q
            ;;
    esac
}

#----------------------------------------------------------------

w_metadata vjrun20 dlls \
    title="MS Visual J# 2.0 SE libraries (requires dotnet20)" \
    publisher="Microsoft" \
    year="2007" \
    media="download" \
    file1="vjredist.exe" \
    installed_file1="c:/windows/Microsoft.NET/Framework/VJSharp/VJSharpSxS10.dll"

load_vjrun20()
{
    w_package_unsupported_win64

    w_call dotnet20

    # See https://www.microsoft.com/en-us/download/details.aspx?id=18084
    w_download ${W_DOWNLOADURLS}/vjredist.exe cf8f3dd4ad41453a302870b74de1c6489e7ed255ad3f652ce4af0b424a933b41
    w_try_cd "$W_CACHE"/"$W_PACKAGE"
    w_try "$WINE" vjredist.exe ${W_OPT_UNATTENDED:+ /q /C:"install $W_UNATTENDED_SLASH_QNT"}
}

#----------------------------------------------------------------

w_metadata vulkanrt dlls \
    title="Vulkan Runtime 1.2.141.2" \
    publisher="LunarG" \
    year="2020" \
    media="download" \
    file1="vulkan-runtime-1.2.141.2.exe" \
    installed_exe1="$W_SYSTEM32_DLLS_WIN/vulkaninfo.exe"

load_vulkanrt()
{
    # https://vulkan.lunarg.com/sdk/home
    w_download "${W_DOWNLOADURLS}/vulkan-runtime-1.2.141.2.exe" cfec461b17aff521cf06b727aa612d654d4e72de8e3c21bd219e77b87f56f20a VulkanRT-1.1.73.0-Installer.exe
    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try "$WINE" "$file1" $W_UNATTENDED_SLASH_S
}

#----------------------------------------------------------------

w_metadata vulkansdk apps \
    title="Vulkan SDK 1.2.141.2" \
    publisher="LunarG" \
    year="2020" \
    media="download" \
    file1="vulkan-sdk-1.2.141.2.exe" \
    installed_file1="C:/VulkanSDK/1.2.141.2/Vulkan.ico" \
    installed_file2="C:/windows/winevulkan.json"

load_vulkansdk()
{
    _W_vulkan_version="${file1%-*.exe}"
    _W_vulkan_version="${_W_vulkan_version#*-}"
    # https://vulkan.lunarg.com/sdk/home
    w_download "${W_DOWNLOADURLS}/vulkan-sdk-1.2.141.2.exe" a5d193f97db4de97e6b4fdd81f00ff6a603f66bb17dc3cf8ac0fe9aec58497c7 VulkanSDK-1.1.73.0-Installer.exe
    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try "$WINE" "$file1" $W_UNATTENDED_SLASH_S
    echo "Creating C:\\windows\\winevulkan.json winevulkan json file"
    cat > "$W_WINDIR_UNIX"/winevulkan.json <<_EOF_
{
    "file_format_version": "1.0.0",
    "ICD": {
        "library_path": "c:\\\\windows\\\\system32\\\\winevulkan.dll",
        "api_version": "$_W_vulkan_version"
    }
}
_EOF_
    echo "Creating winevulkan registry settings"
    cat > "$W_TMP"/winevulkan.reg <<_EOF_
REGEDIT4

[HKEY_LOCAL_MACHINE\\SOFTWARE\\Khronos\\Vulkan\\Drivers\\]
"C:\\\\Windows\\\\winevulkan.json"=dword:00000000

_EOF_
    w_try_regedit "$W_TMP_WIN"\\winevulkan.reg
}

#----------------------------------------------------------------

w_metadata webio dlls \
    title="MS Windows Web I/O" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/webio.dll"

load_webio()
{
    helper_win7sp1 x86_microsoft-windows-webio_31bf3856ad364e35_6.1.7601.17514_none_5ef1a4093cf55387/webio.dll
    w_try cp "$W_TMP/x86_microsoft-windows-webio_31bf3856ad364e35_6.1.7601.17514_none_5ef1a4093cf55387/webio.dll" "$W_SYSTEM32_DLLS/webio.dll"

    if [ "$W_ARCH" = "win64" ]; then
        helper_win7sp1_x64 amd64_microsoft-windows-webio_31bf3856ad364e35_6.1.7601.17514_none_bb103f8cf552c4bd/webio.dll
        w_try cp "$W_TMP/amd64_microsoft-windows-webio_31bf3856ad364e35_6.1.7601.17514_none_bb103f8cf552c4bd/webio.dll" "$W_SYSTEM64_DLLS/webio.dll"
    fi

    w_override_dlls native,builtin webio
}


#----------------------------------------------------------------

w_metadata windowscodecs dlls \
    title="MS Windows Imaging Component" \
    publisher="Microsoft" \
    year="2006" \
    media="download" \
    file1="wic_x86_enu.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/WindowsCodecs.dll"

load_windowscodecs()
{
    # Separate 32/64-bit installers:
    if [ "$W_ARCH" = "win32" ] ; then
        # https://www.microsoft.com/en-us/download/details.aspx?id=32
        w_download ${W_DOWNLOADURLS}/wic_x86_enu.exe 196868b09d87ae04e4ab42b4a3e0abbb160500e8ff13deb38e2956ee854868b1
        EXE="wic_x86_enu.exe"
    elif [ "$W_ARCH" = "win64" ] ; then
        # https://www.microsoft.com/en-us/download/details.aspx?id=1385
        w_download ${W_DOWNLOADURLS}/wic_x64_enu.exe 5822fecd69a90c2833965a25e8779000825d69cc8c9250933f0ab70df52171e1
        EXE="wic_x64_enu.exe"
    else
        w_die "Invalid W_ARCH value, $W_ARCH"
    fi

    # Avoid a file existence check.
    w_try rm -f "$W_SYSTEM32_DLLS"/windowscodecs.dll "$W_SYSTEM32_DLLS"/windowscodecsext.dll "$W_SYSTEM32_DLLS"/wmphoto.dll "$W_SYSTEM32_DLLS"/photometadatahandler.dll

    if [ "$W_ARCH" = "win64" ]; then
         w_try rm -f "$W_SYSTEM64_DLLS"/windowscodecs.dll "$W_SYSTEM64_DLLS"/windowscodecsext.dll "$W_SYSTEM64_DLLS"/wmphoto.dll "$W_SYSTEM64_DLLS"/photometadatahandler.dll
    fi

    # AF says in AppDB entry for .NET 3.0 that windowscodecs has to be native only
    w_override_dlls native windowscodecs windowscodecsext

    # Previously this was winxp, but that didn't work for 64-bit, see https://github.com/Winetricks/winetricks/issues/970
    w_set_winver win2k3

    # Always run the WIC installer in passive mode.
    # See https://bugs.winehq.org/show_bug.cgi?id=16876 and
    # https://bugs.winehq.org/show_bug.cgi?id=23232
    w_try_cd "$W_CACHE/$W_PACKAGE"

    if w_workaround_wine_bug 32859 "Working around possibly broken libX11"; then
        w_try $W_TASKSET "$WINE" "$EXE" /passive
    else
        w_try "$WINE" "$EXE" /passive
    fi

    w_set_winver 'default'
}

#----------------------------------------------------------------

w_metadata winhttp dlls \
    title="MS Windows HTTP Services" \
    publisher="Microsoft" \
    year="2005" \
    media="download" \
    file1="../win2ksp4/W2KSP4_EN.EXE" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/winhttp.dll"

load_winhttp()
{
    # 2017/10/12: Can't use win7's version, as that need webio.dll, which wants ntdll.EtwEventActivityIdControl.
    # Should get that into wine{,-stable} so we can use win7 version in the long run
    # See https://github.com/Winetricks/winetricks/issues/831

    helper_win2ksp4 i386/new/winhttp.dl_
    w_try_cabextract --directory="$W_SYSTEM32_DLLS" "$W_TMP"/i386/new/winhttp.dl_
    w_override_dlls native,builtin winhttp
}

#----------------------------------------------------------------

w_metadata wininet dlls \
    title="MS Windows Internet API" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/wininet.dll"

load_wininet()
{
    helper_win7sp1 x86_microsoft-windows-i..tocolimplementation_31bf3856ad364e35_8.0.7601.17514_none_1eaaa4a07717236e/wininet.dll
    w_try cp "$W_TMP/x86_microsoft-windows-i..tocolimplementation_31bf3856ad364e35_8.0.7601.17514_none_1eaaa4a07717236e/wininet.dll" "$W_SYSTEM32_DLLS/wininet.dll"

    if [ "$W_ARCH" = "win64" ]; then
        helper_win7sp1_x64 amd64_microsoft-windows-i..tocolimplementation_31bf3856ad364e35_8.0.7601.17514_none_7ac940242f7494a4/wininet.dll
        w_try cp "$W_TMP/amd64_microsoft-windows-i..tocolimplementation_31bf3856ad364e35_8.0.7601.17514_none_7ac940242f7494a4/wininet.dll" "$W_SYSTEM64_DLLS/wininet.dll"
    fi

    w_override_dlls native,builtin wininet

    w_call iertutil
}

#----------------------------------------------------------------

w_metadata wininet_win2k dlls \
    title="MS Windows Internet API" \
    publisher="Microsoft" \
    year="2008" \
    media="download" \
    file1="../win2ksp4/W2KSP4_EN.EXE" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/wininet.dll"

load_wininet_win2k()
{
    helper_win2ksp4 i386/wininet.dl_
    w_try_cabextract --directory="$W_SYSTEM32_DLLS" "$W_TMP"/i386/wininet.dl_

    w_override_dlls native,builtin wininet
}

#----------------------------------------------------------------

w_metadata wmi dlls \
    title="Windows Management Instrumentation (aka WBEM) Core 1.5" \
    publisher="Microsoft" \
    year="2000" \
    media="download" \
    file1="wmi9x.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/wbem/wbemcore.dll"

load_wmi()
{
    w_package_unsupported_win64

    # WMI for NT4.0 need validation: https://www.microsoft.com/en-us/download/details.aspx?id=7665
    # See also https://www.microsoft.com/en-us/download/details.aspx?id=16510
    # Originally at: https://download.microsoft.com/download/platformsdk/wmi9x/1.5/W9X/EN-US/wmi9x.exe
    # Mirror list: https://filemare.com/en-us/search/wmi9x.exe/761569271
    # 2017/10/14: ftp://59.124.141.94 is dead, using ftp://82.162.138.211
    # 2018/06/03: ftp://82.162.138.211 is dead, moved to ftp://ftp.espe.edu.ec
    # 2019/12/22: all ftp mirrors I found are dead, so use wayback machine for original MS url
    w_download ${W_DOWNLOADURLS}/wmi9x.exe 1d5d94050354b164c6a19531df151e0703d5eb39cebf4357ee2cfc340c2509d0

    w_set_winver win98
    w_override_dlls native,builtin wbemprox wmiutils

    # Note: there is a crash in the background towards the end, doesn't seem to hurt; see https://bugs.winehq.org/show_bug.cgi?id=7920
    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try "$WINE" wmi9x.exe $W_UNATTENDED_SLASH_S
    w_killall "WinMgmt.exe"

    w_set_winver 'default'
}

#----------------------------------------------------------------

w_metadata wmv9vcm dlls \
    title="MS Windows Media Video 9 Video Compression Manager" \
    publisher="Microsoft" \
    year="2013" \
    media="download" \
    file1="WindowsServer2003-WindowsMedia-KB2845142-x86-ENU.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/wmv9vcm.dll"

load_wmv9vcm()
{
    # https://www.microsoft.com/en-us/download/details.aspx?id=39486
    # See also https://www.microsoft.com/en-us/download/details.aspx?id=6191
    w_download ${W_DOWNLOADURLS}/WindowsServer2003-WindowsMedia-KB2845142-x86-ENU.exe 51e11691339c1c817b12f92e613145ffcd7b6f7e869d994cc8dbc4591b24f155
    w_try_cabextract --directory="$W_TMP" "$W_CACHE/$W_PACKAGE/$file1"
    w_try cp -f "$W_TMP"/wm64/wmv9vcm.dll "$W_SYSTEM32_DLLS"

    # Register codec:
    cat > "$W_TMP"/tmp.reg <<_EOF_
REGEDIT4
[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32]
"vidc.WMV3"="wmv9vcm.dll"

_EOF_
    w_try_regedit "$W_TMP_WIN"\\tmp.reg
}

#----------------------------------------------------------------

w_metadata wsh57 dlls \
    title="MS Windows Script Host 5.7" \
    publisher="Microsoft" \
    year="2007" \
    media="download" \
    file1="scripten.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/scrrun.dll"

load_wsh57()
{
    # See also https://www.microsoft.com/en-us/download/details.aspx?id=8247
    w_download ${W_DOWNLOADURLS}/scripten.exe 63c781b9e50bfd55f10700eb70b5c571a9bedfd8d35af29f6a22a77550df5e7b

    w_try_cabextract -d "$W_SYSTEM32_DLLS" "$W_CACHE"/wsh57/scripten.exe

    # Wine doesn't provide the other dll's (yet?)
    w_override_dlls native,builtin jscript scrrun vbscript cscript.exe wscript.exe
    w_try_regsvr dispex.dll jscript.dll scrobj.dll scrrun.dll vbscript.dll wshcon.dll wshext.dll
}

#----------------------------------------------------------------

w_metadata xact dlls \
    title="MS XACT Engine (32-bit only)" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/xactengine2_0.dll"

load_xact()
{
    helper_directx_Jun2010

    # Extract xactengine?_?.dll, X3DAudio?_?.dll, xaudio?_?.dll, xapofx?_?.dll
    w_try_cabextract -d "$W_TMP" -L -F '*_xact_*x86*' "$W_CACHE/directx9/$DIRECTX_NAME"
    w_try_cabextract -d "$W_TMP" -L -F '*_x3daudio_*x86*' "$W_CACHE/directx9/$DIRECTX_NAME"
    w_try_cabextract -d "$W_TMP" -L -F '*_xaudio_*x86*' "$W_CACHE/directx9/$DIRECTX_NAME"

    for x in "$W_TMP"/*.cab ; do
        w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'xactengine*.dll' "$x"
        w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'xaudio*.dll' "$x"
        w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'x3daudio*.dll' "$x"
        w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'xapofx*.dll' "$x"
    done

    # Don't install 64-bit xact DLLs by default. They are broken in Wine, see:
    # https://bugs.winehq.org/show_bug.cgi?id=41618#c5

    w_override_dlls native,builtin xaudio2_0 xaudio2_1 xaudio2_2 xaudio2_3 xaudio2_4 xaudio2_5 xaudio2_6 xaudio2_7
    w_override_dlls native,builtin x3daudio1_0 x3daudio1_1 x3daudio1_2 x3daudio1_3 x3daudio1_4 x3daudio1_5 x3daudio1_6 x3daudio1_7
    w_override_dlls native,builtin xapofx1_1 xapofx1_2 xapofx1_3 xapofx1_4 xapofx1_5

    # Register xactengine?_?.dll
    for x in "$W_SYSTEM32_DLLS"/xactengine* ; do
        w_try_regsvr "$(basename "$x")"
    done

    # and xaudio?_?.dll, but not xaudio2_8 (unsupported)
    for x in 0 1 2 3 4 5 6 7 ; do
        w_try_regsvr "$(basename "$W_SYSTEM32_DLLS/xaudio2_${x}")"
    done
}

#----------------------------------------------------------------

w_metadata xact_x64 dlls \
    title="MS XACT Engine (64-bit only)" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_Jun2010_redist.exe" \
    installed_file1="${W_SYSTEM64_DLLS_WIN64:-does_not_exist}/xactengine2_0.dll"

load_xact_x64()
{
    w_package_unsupported_win32
    if w_workaround_wine_bug 41618; then
        w_warn "While this helps some games, it completely breaks others. You've been warned."
    fi

    helper_directx_Jun2010

    # Extract xactengine?_?.dll, X3DAudio?_?.dll, xaudio?_?.dll, xapofx?_?.dll
    w_try_cabextract -d "$W_TMP" -L -F '*_xact_*x64*' "$W_CACHE/directx9/$DIRECTX_NAME"
    w_try_cabextract -d "$W_TMP" -L -F '*_x3daudio_*x64*' "$W_CACHE/directx9/$DIRECTX_NAME"
    w_try_cabextract -d "$W_TMP" -L -F '*_xaudio_*x64*' "$W_CACHE/directx9/$DIRECTX_NAME"

    for x in "$W_TMP"/*.cab ; do
        w_try_cabextract -d "$W_SYSTEM64_DLLS" -L -F 'xactengine*.dll' "$x"
        w_try_cabextract -d "$W_SYSTEM64_DLLS" -L -F 'xaudio*.dll' "$x"
        w_try_cabextract -d "$W_SYSTEM64_DLLS" -L -F 'x3daudio*.dll' "$x"
        w_try_cabextract -d "$W_SYSTEM64_DLLS" -L -F 'xapofx*.dll' "$x"
    done

    w_override_dlls native,builtin xaudio2_0 xaudio2_1 xaudio2_2 xaudio2_3 xaudio2_4 xaudio2_5 xaudio2_6 xaudio2_7
    w_override_dlls native,builtin x3daudio1_0 x3daudio1_1 x3daudio1_2 x3daudio1_3 x3daudio1_4 x3daudio1_5 x3daudio1_6 x3daudio1_7
    w_override_dlls native,builtin xapofx1_1 xapofx1_2 xapofx1_3 xapofx1_4 xapofx1_5

    # Register xactengine?_?.dll
    for x in "$W_SYSTEM64_DLLS"/xactengine* ; do
        w_try_regsvr64 "$(basename "$x")"
    done

    # and xaudio?_?.dll, but not xaudio2_8 (unsupported)
    for x in 0 1 2 3 4 5 6 7 ; do
        w_try_regsvr64 "$(basename "$W_SYSTEM64_DLLS/xaudio2_${x}")"
    done
}

#----------------------------------------------------------------

w_metadata xinput dlls \
    title="Microsoft XInput (Xbox controller support)" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="../directx9/directx_feb2010_redist.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/xinput1_1.dll"

load_xinput()
{
    helper_directx_Jun2010

    w_try_cabextract -d "$W_TMP" -L -F '*_xinput_*x86*' "$W_CACHE"/directx9/$DIRECTX_NAME
    for x in "$W_TMP"/*.cab; do
      w_try_cabextract -d "$W_SYSTEM32_DLLS" -L -F 'xinput*.dll' "$x"
    done
    if test "$W_ARCH" = "win64"; then
        w_try_cabextract -d "$W_TMP" -L -F '*_xinput_*x64*' "$W_CACHE"/directx9/$DIRECTX_NAME
        for x in "$W_TMP"/*x64.cab; do
            w_try_cabextract -d "$W_SYSTEM64_DLLS" -L -F 'xinput*.dll' "$x"
        done
    fi
    w_override_dlls native xinput1_1
    w_override_dlls native xinput1_2
    w_override_dlls native xinput1_3
    w_override_dlls native xinput9_1_0
}

#----------------------------------------------------------------

w_metadata xmllite dlls \
    title="MS xmllite dll" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="../win7sp1/windows6.1-KB976932-X86.exe" \
    installed_file1="$W_SYSTEM32_DLLS_WIN/xmllite.dll"

load_xmllite()
{
    helper_win7sp1 x86_microsoft-windows-servicingstack_31bf3856ad364e35_6.1.7601.17514_none_0b66cb34258c936f/xmllite.dll
    w_try cp "$W_TMP/x86_microsoft-windows-servicingstack_31bf3856ad364e35_6.1.7601.17514_none_0b66cb34258c936f/xmllite.dll" "$W_SYSTEM32_DLLS/xmllite.dll"

    if [ "$W_ARCH" = "win64" ]; then
        helper_win7sp1_x64 amd64_microsoft-windows-servicingstack_31bf3856ad364e35_6.1.7601.17514_none_678566b7ddea04a5/xmllite.dll "$W_SYSTEM64_DLLS/xmllite.dll"
        w_try cp "$W_TMP/amd64_microsoft-windows-servicingstack_31bf3856ad364e35_6.1.7601.17514_none_678566b7ddea04a5/xmllite.dll" "$W_SYSTEM64_DLLS/xmllite.dll"
    fi

    w_override_dlls native,builtin xmllite
}

#----------------------------------------------------------------

w_metadata xna31 dlls \
    title="MS XNA Framework Redistributable 3.1" \
    publisher="Microsoft" \
    year="2009" \
    media="download" \
    file1="xnafx31_redist.msi" \
    installed_file1="C:/windows/assembly/GAC_32/Microsoft.Xna.Framework.Game/3.1.0.0__6d5c3888ef60e27d/Microsoft.Xna.Framework.Game.dll"

load_xna31()
{
    w_call dotnet20sp2
    w_download ${W_DOWNLOADURLS}/xnafx31_redist.msi 187e7e6b08fe35428d945612a7d258bfed25fad53cc54882983abdc73fe60f91
    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try "$WINE" msiexec $W_UNATTENDED_SLASH_QUIET /i "$file1"
}

#----------------------------------------------------------------

w_metadata xna40 dlls \
    title="MS XNA Framework Redistributable 4.0" \
    publisher="Microsoft" \
    year="2010" \
    media="download" \
    file1="xnafx40_redist.msi" \
    installed_file1="$W_PROGRAMS_X86_WIN/Common Files/Microsoft Shared/XNA/Framework/v4.0/XnaNative.dll"

load_xna40()
{
    if w_workaround_wine_bug 30718; then
        w_warn "$W_PACKAGE may not install properly in Wine yet"
    fi

    # See https://bugs.winehq.org/show_bug.cgi?id=30718#c8
    export COMPlus_OnlyUseLatestCLR=1
    w_call dotnet40

    # https://www.microsoft.com/en-us/download/details.aspx?id=20914
    w_download ${W_DOWNLOADURLS}/xnafx40_redist.msi e6c41d692ebcba854dad4b1c52bb7ddd05926bad3105595d6596b8bab01c25e7
    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try "$WINE" msiexec $W_UNATTENDED_SLASH_QUIET /i "$file1"
}

#----------------------------------------------------------------

w_metadata xvid dlls \
    title="Xvid Video Codec" \
    publisher="xvid.org" \
    year="2009" \
    media="download" \
    file1="Xvid-1.3.2-20110601.exe" \
    installed_file1="$W_PROGRAMS_X86_WIN/Xvid/xvid.ico"

load_xvid()
{
    w_call vcrun6
    w_download ${W_DOWNLOADURLS}/Xvid-1.3.2-20110601.exe 74b23965cebe59e388eab6dba224b6b751ef4519454cc12086ade51c81f0a33c
    w_try_cd "$W_CACHE/$W_PACKAGE"
    w_try "$WINE" "$file1" ${W_OPT_UNATTENDED:+ --mode unattended --decode_divx 1 --decode_3ivx 1 --decode_other 1}
}

#######################
# fonts
#######################

w_metadata baekmuk fonts \
    title="Baekmuk Korean fonts" \
    publisher="Wooderart Inc. / kldp.net" \
    year="1999" \
    media="download" \
    file1="fonts-baekmuk_2.2.orig.tar.gz" \
    installed_file1="$W_FONTSDIR_WIN/batang.ttf"

load_baekmuk()
{
    # See http://kldp.net/projects/baekmuk for project page
    # Need to download from Debian as the project page has unique captcha tokens per visitor
    w_download "${W_DOWNLOADURLS}/fonts-baekmuk_2.2.orig.tar.gz" 08ab7dffb55d5887cc942ce370f5e33b756a55fbb4eaf0b90f244070e8d51882

    w_try_cd "$W_TMP"
    w_try tar -zxf "$W_CACHE/$W_PACKAGE/$file1" baekmuk-ttf-2.2/ttf
    w_try_cp_font_files baekmuk-ttf-2.2/ttf/ "$W_FONTSDIR_UNIX"
    w_register_font batang.ttf "Baekmuk Batang"
    w_register_font gulim.ttf "Baekmuk Gulim"
    w_register_font dotum.ttf "Baekmuk Dotum"
    w_register_font hline.ttf "Baekmuk Headline"
}

#----------------------------------------------------------------

w_metadata cjkfonts fonts \
    title="All Chinese, Japanese, Korean fonts and aliases" \
    publisher="Various" \
    date="1999-2019" \
    media="download"

load_cjkfonts()
{
    w_call fakechinese
    w_call fakejapanese
    w_call fakekorean
    w_call unifont
}

#----------------------------------------------------------------

w_metadata calibri fonts \
    title="MS Calibri font" \
    publisher="Microsoft" \
    year="2007" \
    media="download" \
    file1="PowerPointViewer.exe" \
    installed_file1="$W_FONTSDIR_WIN/calibri.ttf"

load_calibri()
{
    # https://www.microsoft.com/en-us/download/details.aspx?id=13
    # Originally at https://download.microsoft.com/download/E/6/7/E675FFFC-2A6D-4AB0-B3EB-27C9F8C8F696/PowerPointViewer.exe
    w_download_to PowerPointViewer "${W_DOWNLOADURLS}/PowerPointViewer.exe" 249473568eba7a1e4f95498acba594e0f42e6581add4dead70c1dfb908a09423
    w_try_cabextract -d "$W_TMP" -F "ppviewer.cab" "$W_CACHE/PowerPointViewer/$file1"
    w_try_cabextract -d "$W_TMP" -F "CALIBRI*.TTF" "$W_TMP/ppviewer.cab"
    w_try_cp_font_files "$W_TMP" "$W_FONTSDIR_UNIX" "CALIBRI*.TTF"
    w_register_font calibri.ttf "Calibri"
    w_register_font calibrib.ttf "Calibri Bold"
    w_register_font calibrii.ttf "Calibri Italic"
    w_register_font calibriz.ttf "Calibri Bold Italic"
}

#----------------------------------------------------------------

w_metadata cambria fonts \
    title="MS Cambria font" \
    publisher="Microsoft" \
    year="2009" \
    media="download" \
    file1="PowerPointViewer.exe" \
    installed_file1="$W_FONTSDIR_WIN/cambria.ttc"

load_cambria()
{
    # https://www.microsoft.com/en-us/download/details.aspx?id=13
    # Originally at https://download.microsoft.com/download/E/6/7/E675FFFC-2A6D-4AB0-B3EB-27C9F8C8F696/PowerPointViewer.exe
    w_download_to PowerPointViewer "${W_DOWNLOADURLS}/PowerPointViewer.exe" 249473568eba7a1e4f95498acba594e0f42e6581add4dead70c1dfb908a09423
    w_try_cabextract -d "$W_TMP" -F "ppviewer.cab" "$W_CACHE/PowerPointViewer/$file1"
    w_try_cabextract -d "$W_TMP" -F "CAMBRIA*.TT*" "$W_TMP/ppviewer.cab"
    w_try_cp_font_files "$W_TMP" "$W_FONTSDIR_UNIX" "CAMBRIA*.TT*"
    w_register_font cambria.ttc "Cambria & Cambria Math"
    w_register_font cambriab.ttf "Cambria Bold"
    w_register_font cambriai.ttf "Cambria Italic"
    w_register_font cambriaz.ttf "Cambria Bold Italic"
}

#----------------------------------------------------------------

w_metadata candara fonts \
    title="MS Candara font" \
    publisher="Microsoft" \
    year="2009" \
    media="download" \
    file1="PowerPointViewer.exe" \
    installed_file1="$W_FONTSDIR_WIN/candara.ttf"

load_candara()
{
    # https://www.microsoft.com/en-us/download/details.aspx?id=13
    # Originally at https://download.microsoft.com/download/E/6/7/E675FFFC-2A6D-4AB0-B3EB-27C9F8C8F696/PowerPointViewer.exe
    w_download_to PowerPointViewer "${W_DOWNLOADURLS}/PowerPointViewer.exe" 249473568eba7a1e4f95498acba594e0f42e6581add4dead70c1dfb908a09423
    w_try_cabextract -d "$W_TMP" -F "ppviewer.cab" "$W_CACHE/PowerPointViewer/$file1"
    w_try_cabextract -d "$W_TMP" -F "CANDARA*.TTF" "$W_TMP/ppviewer.cab"
    w_try_cp_font_files "$W_TMP" "$W_FONTSDIR_UNIX" "CANDARA*.TTF"
    w_register_font candara.ttf "Candara"
    w_register_font candarab.ttf "Candara Bold"
    w_register_font candarai.ttf "Candara Italic"
    w_register_font candaraz.ttf "Candara Bold Italic"
}

#----------------------------------------------------------------

w_metadata consolas fonts \
    title="MS Consolas console font" \
    publisher="Microsoft" \
    year="2011" \
    media="download" \
    file1="PowerPointViewer.exe" \
    installed_file1="$W_FONTSDIR_WIN/consola.ttf"

load_consolas()
{
    # https://www.microsoft.com/en-us/download/details.aspx?id=13
    # Originally at https://download.microsoft.com/download/E/6/7/E675FFFC-2A6D-4AB0-B3EB-27C9F8C8F696/PowerPointViewer.exe
    w_download_to PowerPointViewer "${W_DOWNLOADURLS}/PowerPointViewer.exe" 249473568eba7a1e4f95498acba594e0f42e6581add4dead70c1dfb908a09423
    w_try_cabextract -d "$W_TMP" -F "ppviewer.cab" "$W_CACHE/PowerPointViewer/$file1"
    w_try_cabextract -d "$W_TMP" -F "CONSOLA*.TTF" "$W_TMP/ppviewer.cab"
    w_try_cp_font_files "$W_TMP" "$W_FONTSDIR_UNIX" "CONSOLA*.TTF"
    w_register_font consola.ttf "Consolas"
    w_register_font consolab.ttf "Consolas Bold"
    w_register_font consolai.ttf "Consolas Italic"
    w_register_font consolaz.ttf "Consolas Bold Italic"
}

#----------------------------------------------------------------

w_metadata constantia fonts \
    title="MS Constantia font" \
    publisher="Microsoft" \
    year="2009" \
    media="download" \
    file1="PowerPointViewer.exe" \
    installed_file1="$W_FONTSDIR_WIN/constan.ttf"

load_constantia()
{
    # https://www.microsoft.com/en-us/download/details.aspx?id=13
    # Originally at https://download.microsoft.com/download/E/6/7/E675FFFC-2A6D-4AB0-B3EB-27C9F8C8F696/PowerPointViewer.exe
    w_download_to PowerPointViewer "${W_DOWNLOADURLS}/PowerPointViewer.exe" 249473568eba7a1e4f95498acba594e0f42e6581add4dead70c1dfb908a09423
    w_try_cabextract -d "$W_TMP" -F "ppviewer.cab" "$W_CACHE/PowerPointViewer/$file1"
    w_try_cabextract -d "$W_TMP" -F "CONSTAN*.TTF" "$W_TMP/ppviewer.cab"
    w_try_cp_font_files "$W_TMP" "$W_FONTSDIR_UNIX" "CONSTAN*.TTF"
    w_register_font constan.ttf "Constantia"
    w_register_font constanb.ttf "Constantia Bold"
    w_register_font constani.ttf "Constantia Italic"
    w_register_font constanz.ttf "Constantia Bold Italic"
}

#----------------------------------------------------------------

w_metadata corbel fonts \
    title="MS Corbel font" \
    publisher="Microsoft" \
    year="2009" \
    media="download" \
    file1="PowerPointViewer.exe" \
    installed_file1="$W_FONTSDIR_WIN/corbel.ttf"

load_corbel()
{
    # https://www.microsoft.com/en-us/download/details.aspx?id=13
    # Originally at https://download.microsoft.com/download/E/6/7/E675FFFC-2A6D-4AB0-B3EB-27C9F8C8F696/PowerPointViewer.exe
    w_download_to PowerPointViewer "${W_DOWNLOADURLS}/PowerPointViewer.exe" 249473568eba7a1e4f95498acba594e0f42e6581add4dead70c1dfb908a09423
    w_try_cabextract -d "$W_TMP" -F "ppviewer.cab" "$W_CACHE/PowerPointViewer/$file1"
    w_try_cabextract -d "$W_TMP" -F "CORBEL*.TTF" "$W_TMP/ppviewer.cab"
    w_try_cp_font_files "$W_TMP" "$W_FONTSDIR_UNIX" "CORBEL*.TTF"
    w_register_font corbel.ttf "Corbel"
    w_register_font corbelb.ttf "Corbel Bold"
    w_register_font corbeli.ttf "Corbel Italic"
    w_register_font corbelz.ttf "Corbel Bold Italic"
}

#----------------------------------------------------------------

w_metadata meiryo fonts \
    title="MS Meiryo font" \
    publisher="Microsoft" \
    year="2009" \
    media="download" \
    conflicts="fakejapanese_vlgothic" \
    file1="PowerPointViewer.exe" \
    installed_file1="$W_FONTSDIR_WIN/meiryo.ttc"

load_meiryo()
{
    # https://www.microsoft.com/en-us/download/details.aspx?id=13
    # Originally at https://download.microsoft.com/download/E/6/7/E675FFFC-2A6D-4AB0-B3EB-27C9F8C8F696/PowerPointViewer.exe
    w_download_to PowerPointViewer "${W_DOWNLOADURLS}/PowerPointViewer.exe" 249473568eba7a1e4f95498acba594e0f42e6581add4dead70c1dfb908a09423
    w_try_cabextract -d "$W_TMP" -F "ppviewer.cab" "$W_CACHE/PowerPointViewer/$file1"
    w_try_cabextract -d "$W_TMP" -F "MEIRYO*.TTC" "$W_TMP/ppviewer.cab"
    w_try_cp_font_files "$W_TMP" "$W_FONTSDIR_UNIX" "MEIRYO*.TTC"
    w_register_font meiryo.ttc "Meiryo & Meiryo Italic & Meiryo UI & Meiryo UI Italic"
    w_register_font meiryob.ttc "Meiryo Bold & Meiryo Bold Italic & Meiryo UI Bold & Meiryo UI Bold Italic"
}

#----------------------------------------------------------------

w_metadata pptfonts fonts \
    title="All MS PowerPoint Viewer fonts" \
    publisher="various" \
    date="2007-2009" \
    media="download"

load_pptfonts()
{
    w_call calibri
    w_call cambria
    w_call candara
    w_call consolas
    w_call constantia
    w_call corbel
    w_call meiryo
}

#----------------------------------------------------------------

w_metadata andale fonts \
    title="MS Andale Mono font" \
    publisher="Microsoft" \
    year="2008" \
    media="download" \
    file1="andale32.exe" \
    installed_file1="$W_FONTSDIR_WIN/andalemo.ttf"

load_andale()
{
    w_download_to corefonts "${W_DOWNLOADURLS}/andale32.exe" 0524fe42951adc3a7eb870e32f0920313c71f170c859b5f770d82b4ee111e970
    w_try_cabextract -d "$W_TMP" "$W_CACHE"/corefonts/andale32.exe
    w_try_cp_font_files "$W_TMP" "$W_FONTSDIR_UNIX" "AndaleMo.TTF"
    w_register_font andalemo.ttf "Andale Mono"
}

#----------------------------------------------------------------

w_metadata arial fonts \
    title="MS Arial / Arial Black fonts" \
    publisher="Microsoft" \
    year="2008" \
    media="download" \
    file1="arial32.exe" \
    installed_file1="$W_FONTSDIR_WIN/arial.ttf"

load_arial()
{
    w_download_to corefonts "${W_DOWNLOADURLS}/arial32.exe" 85297a4d146e9c87ac6f74822734bdee5f4b2a722d7eaa584b7f2cbf76f478f6
    w_download_to corefonts "${W_DOWNLOADURLS}/arialb32.exe" a425f0ffb6a1a5ede5b979ed6177f4f4f4fdef6ae7c302a7b7720ef332fec0a8

    w_try_cabextract -d "$W_TMP" "$W_CACHE"/corefonts/arial32.exe
    w_try_cp_font_files "$W_TMP" "$W_FONTSDIR_UNIX" "Arial*.TTF"
    w_register_font arialbd.ttf "Arial Bold"
    w_register_font arialbi.ttf "Arial Bold Italic"
    w_register_font ariali.ttf "Arial Italic"
    w_register_font arial.ttf "Arial"

    w_try_cabextract -d "$W_TMP" "$W_CACHE"/corefonts/arialb32.exe
    w_try_cp_font_files "$W_TMP" "$W_FONTSDIR_UNIX" "AriBlk.TTF"
    w_register_font ariblk.ttf "Arial Black"
}

#----------------------------------------------------------------

w_metadata comicsans fonts \
    title="MS Comic Sans fonts" \
    publisher="Microsoft" \
    year="2008" \
    media="download" \
    file1="comic32.exe" \
    installed_file1="$W_FONTSDIR_WIN/comic.ttf"

load_comicsans()
{
    w_download_to corefonts "${W_DOWNLOADURLS}/comic32.exe" 9c6df3feefde26d4e41d4a4fe5db2a89f9123a772594d7f59afd062625cd204e
    w_try_cabextract -d "$W_TMP" "$W_CACHE"/corefonts/comic32.exe
    w_try_cp_font_files "$W_TMP" "$W_FONTSDIR_UNIX" "Comic*.TTF"
    w_register_font comicbd.ttf "Comic Sans MS Bold"
    w_register_font comic.ttf "Comic Sans MS"
}

#----------------------------------------------------------------

w_metadata courier fonts \
    title="MS Courier fonts" \
    publisher="Microsoft" \
    year="2008" \
    media="download" \
    file1="courie32.exe" \
    installed_file1="$W_FONTSDIR_WIN/cour.ttf"
load_courier()
{
    w_download_to corefonts "${W_DOWNLOADURLS}/courie32.exe" bb511d861655dde879ae552eb86b134d6fae67cb58502e6ff73ec5d9151f3384
    w_try_cabextract -d "$W_TMP" "$W_CACHE"/corefonts/courie32.exe
    w_try_cp_font_files "$W_TMP" "$W_FONTSDIR_UNIX" "cour*.ttf"
    w_register_font courbd.ttf "Courier New Bold"
    w_register_font courbi.ttf "Courier New Bold Italic"
    w_register_font couri.ttf "Courier New Italic"
    w_register_font cour.ttf "Courier New"
}

#----------------------------------------------------------------

w_metadata georgia fonts \
    title="MS Georgia fonts" \
    publisher="Microsoft" \
    year="2008" \
    media="download" \
    file1="georgi32.exe" \
    installed_file1="$W_FONTSDIR_WIN/georgia.ttf"
load_georgia()
{
    w_download_to corefonts "${W_DOWNLOADURLS}/georgi32.exe" 2c2c7dcda6606ea5cf08918fb7cd3f3359e9e84338dc690013f20cd42e930301
    w_try_cabextract -d "$W_TMP" "$W_CACHE"/corefonts/georgi32.exe
    w_try_cp_font_files "$W_TMP" "$W_FONTSDIR_UNIX" "Georgia*.TTF"
    w_register_font georgiab.ttf "Georgia Bold"
    w_register_font georgiai.ttf "Georgia Italic"
    w_register_font georgia.ttf "Georgia"
    w_register_font georgiaz.ttf "Georgia Bold Italic"
}

#----------------------------------------------------------------

w_metadata impact fonts \
    title="MS Impact fonts" \
    publisher="Microsoft" \
    year="2008" \
    media="download" \
    file1="impact32.exe" \
    installed_file1="$W_FONTSDIR_WIN/impact.ttf"

load_impact()
{
    w_download_to corefonts "${W_DOWNLOADURLS}/impact32.exe" 6061ef3b7401d9642f5dfdb5f2b376aa14663f6275e60a51207ad4facf2fccfb
    w_try_cabextract -d "$W_TMP" "$W_CACHE"/corefonts/impact32.exe
    w_try_cp_font_files "$W_TMP" "$W_FONTSDIR_UNIX" "Impact.TTF"
    w_register_font impact.ttf "Impact"
}

#----------------------------------------------------------------

w_metadata times fonts \
    title="MS Times fonts" \
    publisher="Microsoft" \
    year="2008" \
    media="download" \
    file1="times32.exe" \
    installed_file1="$W_FONTSDIR_WIN/times.ttf"

load_times()
{
    w_download_to corefonts "${W_DOWNLOADURLS}/times32.exe" db56595ec6ef5d3de5c24994f001f03b2a13e37cee27bc25c58f6f43e8f807ab
    w_try_cabextract -d "$W_TMP" "$W_CACHE"/corefonts/times32.exe
    w_try_cp_font_files "$W_TMP" "$W_FONTSDIR_UNIX" "Times*.TTF"
    w_register_font timesbd.ttf "Times New Roman Bold"
    w_register_font timesbi.ttf "Times New Roman Bold Italic"
    w_register_font timesi.ttf "Times New Roman Italic"
    w_register_font times.ttf "Times New Roman"
}

#----------------------------------------------------------------

w_metadata trebuchet fonts \
    title="MS Trebuchet fonts" \
    publisher="Microsoft" \
    year="2008" \
    media="download" \
    file1="trebuchet32.exe" \
    installed_file1="$W_FONTSDIR_WIN/trebuc.ttf"

load_trebuchet()
{
    w_download_to corefonts "${W_DOWNLOADURLS}/trebuc32.exe" 5a690d9bb8510be1b8b4fe49f1f2319651fe51bbe54775ddddd8ef0bd07fdac9
    w_try_cabextract -d "$W_TMP" "$W_CACHE"/corefonts/trebuc32.exe
    w_try_cp_font_files "$W_TMP" "$W_FONTSDIR_UNIX" "[tT]rebuc*.ttf"
    w_register_font trebucbd.ttf "Trebuchet MS Bold"
    w_register_font trebucbi.ttf "Trebuchet MS Bold Italic"
    w_register_font trebucit.ttf "Trebuchet MS Italic"
    w_register_font trebuc.ttf "Trebuchet MS"
}

#----------------------------------------------------------------

w_metadata verdana fonts \
    title="MS Verdana fonts" \
    publisher="Microsoft" \
    year="2008" \
    media="download" \
    file1="verdan32.exe" \
    installed_file1="$W_FONTSDIR_WIN/verdana.ttf"

load_verdana()
{
    w_download_to corefonts "${W_DOWNLOADURLS}/verdan32.exe" c1cb61255e363166794e47664e2f21af8e3a26cb6346eb8d2ae2fa85dd5aad96
    w_try_cabextract -d "$W_TMP" "$W_CACHE"/corefonts/verdan32.exe
    w_try_cp_font_files "$W_TMP" "$W_FONTSDIR_UNIX" "Verdana*.TTF"
    w_register_font verdanab.ttf "Verdana Bold"
    w_register_font verdanai.ttf "Verdana Italic"
    w_register_font verdana.ttf "Verdana"
    w_register_font verdanaz.ttf "Verdana Bold Italic"
}

#----------------------------------------------------------------

w_metadata webdings fonts \
    title="MS Webdings fonts" \
    publisher="Microsoft" \
    year="2008" \
    media="download" \
    file1="webdin32.exe" \
    installed_file1="$W_FONTSDIR_WIN/webdings.ttf"

load_webdings()
{
    w_download_to corefonts "${W_DOWNLOADURLS}/webdin32.exe" 64595b5abc1080fba8610c5c34fab5863408e806aafe84653ca8575bed17d75a
    w_try_cabextract -d "$W_TMP" "$W_CACHE"/corefonts/webdin32.exe
    w_try_cp_font_files "$W_TMP" "$W_FONTSDIR_UNIX" "Webdings.TTF"
    w_register_font webdings.ttf "Webdings"
}

#----------------------------------------------------------------

w_metadata corefonts fonts \
    title="MS Arial, Courier, Times fonts" \
    publisher="Microsoft" \
    year="2008" \
    media="download" \
    file1="arial32.exe" \
    installed_file1="$W_FONTSDIR_WIN/corefonts.installed"

load_corefonts()
{
    # Natively installed versions of these fonts will cause the installers
    # to exit silently. Because there are apps out there that depend on the
    # files being present in the Windows font directory we use cabextract
    # to obtain the files and register the fonts by hand.

    w_call andale
    w_call arial
    w_call comicsans
    w_call courier
    w_call georgia
    w_call impact
    w_call times
    w_call trebuchet
    w_call verdana
    w_call webdings

    touch "$W_FONTSDIR_UNIX/corefonts.installed"
}

#----------------------------------------------------------------

w_metadata droid fonts \
    title="Droid fonts" \
    publisher="Ascender Corporation" \
    year="2009" \
    media="download" \
    file1="DroidSans-Bold.ttf" \
    installed_file1="$W_FONTSDIR_WIN/droidsans-bold.ttf"

do_droid() {
    w_download "${_W_droid_url}${1}?raw=true" "$3"  "$1"
    w_try_cp_font_files "$W_CACHE/droid" "$W_FONTSDIR_UNIX" "$1"
    w_register_font "$(echo "$1" | tr "[:upper:]" "[:lower:]")" "$2"
}

load_droid()
{
    # See https://en.wikipedia.org/wiki/Droid_(font)
    # Old URL was http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob_plain;f=data/fonts/'
    # Then it was https://github.com/android/platform_frameworks_base/blob/master/data/fonts/
    # but the fonts are no longer in master. Using an older commit instead:
    _W_droid_url="${W_DOWNLOADURLS}/fonts/"

    do_droid DroidSans-Bold.ttf        "Droid Sans Bold"         2f529a3e60c007979d95d29794c3660694217fb882429fb33919d2245fe969e9
    do_droid DroidSansFallback.ttf     "Droid Sans Fallback"     05d71b179ef97b82cf1bb91cef290c600a510f77f39b4964359e3ef88378c79d
    do_droid DroidSansJapanese.ttf     "Droid Sans Japanese"     935867c21b8484c959170e62879460ae9363eae91f9b35e4519d24080e2eac30
    do_droid DroidSansMono.ttf         "Droid Sans Mono"         12b552de765dc1265d64f9f5566649930dde4dba07da0251d9f92801e70a1047
    do_droid DroidSans.ttf             "Droid Sans"              f51b88945f4c1b236f44b8d55a2d304316869127e95248c435c23f1e4142a7db
    do_droid DroidSerif-BoldItalic.ttf "Droid Serif Bold Italic" 3fdf15b911c04317e5881ae1e4b9faefcdc4bf4cfb60223597d5c9455c3e4156
    do_droid DroidSerif-Bold.ttf       "Droid Serif Bold"        d28533eed8368f047eb5f57a88a91ba2ffc8b69a2dec5e50fe3f0c11ae3f4d8e
    do_droid DroidSerif-Italic.ttf     "Droid Serif Italic"      8a55a4823886234792991dd304dfa1fa120ae99483ec6c2255597d7d913b9a55
    do_droid DroidSerif-Regular.ttf    "Droid Serif"             22aea9471bea5bce1ec3bf7136c84f075b3d11cf09dffdc3dba05e570094cbde

    unset _W_droid_url
}

#----------------------------------------------------------------

w_metadata eufonts fonts \
    title="Updated fonts for Romanian and Bulgarian" \
    publisher="Microsoft" \
    year="2008" \
    media="download" \
    file1="EUupdate.EXE" \
    installed_file1="$W_FONTSDIR_WIN/trebucbd.ttf"

load_eufonts()
{
    # https://www.microsoft.com/en-us/download/details.aspx?id=16083
    w_download "${W_DOWNLOADURLS}/EUupdate.EXE" 464dd2cd5f09f489f9ac86ea7790b7b8548fc4e46d9f889b68d2cdce47e09ea8
    w_try_cabextract -d "$W_TMP" "$W_CACHE"/eufonts/EUupdate.EXE
    w_try_cp_font_files "$W_TMP" "$W_FONTSDIR_UNIX"

    w_register_font arialbd.ttf "Arial Bold"
    w_register_font arialbi.ttf "Arial Bold Italic"
    w_register_font ariali.ttf "Arial Italic"
    w_register_font arial.ttf "Arial"
    w_register_font timesbd.ttf "Times New Roman Bold"
    w_register_font timesbi.ttf "Times New Roman Bold Italic"
    w_register_font timesi.ttf "Times New Roman Italic"
    w_register_font times.ttf "Times New Roman"
    w_register_font trebucbd.ttf "Trebuchet MS Bold"
    w_register_font trebucbi.ttf "Trebuchet MS Bold Italic"
    w_register_font trebucit.ttf "Trebuchet MS Italic"
    w_register_font trebuc.ttf "Trebuchet MS"
    w_register_font verdanab.ttf "Verdana Bold"
    w_register_font verdanai.ttf "Verdana Italian"
    w_register_font verdana.ttf "Verdana"
    w_register_font verdanaz.ttf "Verdana Bold Italic"
}

#----------------------------------------------------------------

w_metadata fakechinese fonts \
    title="Creates aliases for Chinese fonts using Source Han Sans fonts" \
    publisher="Adobe" \
    year="2019"

load_fakechinese()
{
    # Loads Source Han Sans fonts and sets aliases for Microsoft Chinese fonts
    # Reference : https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_fonts
    w_call sourcehansans

    # Simplified Chinese
    w_register_font_replacement "Dengxian" "Source Han Sans SC"
    w_register_font_replacement "FangSong" "Source Han Sans SC"
    w_register_font_replacement "KaiTi" "Source Han Sans SC"
    w_register_font_replacement "Microsoft YaHei" "Source Han Sans SC"
    w_register_font_replacement "Microsoft YaHei UI" "Source Han Sans SC"
    w_register_font_replacement "NSimSun" "Source Han Sans SC"
    w_register_font_replacement "SimHei" "Source Han Sans SC"
    w_register_font_replacement "SimKai" "Source Han Sans SC"
    w_register_font_replacement "SimSun" "Source Han Sans SC"
    w_register_font_replacement "SimSun-ExtB" "Source Han Sans SC"

    # Traditional Chinese
    w_register_font_replacement "DFKai-SB" "Source Han Sans TC"
    w_register_font_replacement "Microsoft JhengHei" "Source Han Sans TC"
    w_register_font_replacement "Microsoft JhengHei UI" "Source Han Sans TC"
    w_register_font_replacement "MingLiU" "Source Han Sans TC"
    w_register_font_replacement "PMingLiU" "Source Han Sans TC"
    w_register_font_replacement "MingLiU-ExtB" "Source Han Sans TC"
    w_register_font_replacement "PMingLiU-ExtB" "Source Han Sans TC"
}

#----------------------------------------------------------------

w_metadata fakejapanese fonts \
    title="Creates aliases for Japanese fonts using Source Han Sans fonts" \
    publisher="Adobe" \
    year="2019"

load_fakejapanese()
{
    # Loads Source Han Sans fonts and sets aliases for Microsoft Japanese fonts
    # Reference : https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_fonts
    w_call sourcehansans

    w_register_font_replacement "Meiryo" "Source Han Sans"
    w_register_font_replacement "Meiryo UI" "Source Han Sans"
    w_register_font_replacement "MS Gothic" "Source Han Sans"
    w_register_font_replacement "MS PGothic" "Source Han Sans"
    w_register_font_replacement "MS Mincho" "Source Han Sans"
    w_register_font_replacement "MS PMincho" "Source Han Sans"
    w_register_font_replacement "MS UI Gothic" "Source Han Sans"
    w_register_font_replacement "UD Digi KyoKasho N-R" "Source Han Sans"
    w_register_font_replacement "UD Digi KyoKasho NK-R" "Source Han Sans"
    w_register_font_replacement "UD Digi KyoKasho NP-R" "Source Han Sans"
    w_register_font_replacement "Yu Gothic" "Source Han Sans"
    w_register_font_replacement "Yu Gothic UI" "Source Han Sans"
    w_register_font_replacement "Yu Mincho" "Source Han Sans"
    w_register_font_replacement "メイリオ" "Source Han Sans"
    w_register_font_replacement "ＭＳ ゴシック" "Source Han Sans"
    w_register_font_replacement "ＭＳ Ｐゴシック" "Source Han Sans"
    w_register_font_replacement "ＭＳ 明朝" "Source Han Sans"
    w_register_font_replacement "ＭＳ Ｐ明朝" "Source Han Sans"
}

#----------------------------------------------------------------

w_metadata fakejapanese_ipamona fonts \
    title="Creates aliases for Japanese fonts using IPAMona fonts" \
    publisher="Jun Kobayashi" \
    year="2008"

load_fakejapanese_ipamona()
{
    w_call ipamona

    # Aliases to set:
    # MS UI Gothic --> IPAMonaUIGothic
    # MS Gothic (ＭＳ ゴシック) --> IPAMonaGothic
    # MS PGothic (ＭＳ Ｐゴシック) --> IPAMonaPGothic
    # MS Mincho (ＭＳ 明朝) --> IPAMonaMincho
    # MS PMincho (ＭＳ Ｐ明朝) --> IPAMonaPMincho

    w_register_font_replacement "MS UI Gothic" "IPAMonaUIGothic"
    w_register_font_replacement "MS Gothic" "IPAMonaGothic"
    w_register_font_replacement "MS PGothic" "IPAMonaPGothic"
    w_register_font_replacement "MS Mincho" "IPAMonaMincho"
    w_register_font_replacement "MS PMincho" "IPAMonaPMincho"
    w_register_font_replacement "ＭＳ ゴシック" "IPAMonaGothic"
    w_register_font_replacement "ＭＳ Ｐゴシック" "IPAMonaPGothic"
    w_register_font_replacement "ＭＳ 明朝" "IPAMonaMincho"
    w_register_font_replacement "ＭＳ Ｐ明朝" "IPAMonaPMincho"
}

#----------------------------------------------------------------

w_metadata fakejapanese_vlgothic fonts \
    title="Creates aliases for Japanese Meiryo fonts using VLGothic fonts" \
    publisher="Project Vine / Daisuke Suzuki" \
    conflicts="meiryo" \
    year="2014"

load_fakejapanese_vlgothic()
{
    w_call vlgothic

    # Aliases to set:
    # Meiryo UI --> VL Gothic
    # Meiryo (メイリオ) --> VL Gothic

    w_register_font_replacement "Meiryo UI" "VL Gothic"
    w_register_font_replacement "Meiryo" "VL Gothic"
    w_register_font_replacement "メイリオ" "VL Gothic"
}

#----------------------------------------------------------------

w_metadata fakekorean fonts \
    title="Creates aliases for Korean fonts using Source Han Sans fonts" \
    publisher="Adobe" \
    year="2019"

load_fakekorean()
{
    # Loads Source Han Sans fonts and sets aliases for Microsoft Korean fonts
    # Reference : https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_fonts
    w_call sourcehansans

    w_register_font_replacement "Batang" "Source Han Sans K"
    w_register_font_replacement "BatangChe" "Source Han Sans K"
    w_register_font_replacement "Dotum" "Source Han Sans K"
    w_register_font_replacement "DotumChe" "Source Han Sans K"
    w_register_font_replacement "Gulim" "Source Han Sans K"
    w_register_font_replacement "GulimChe" "Source Han Sans K"
    w_register_font_replacement "Gungsuh" "Source Han Sans K"
    w_register_font_replacement "GungsuhChe" "Source Han Sans K"
    w_register_font_replacement "Malgun Gothic" "Source Han Sans K"
    w_register_font_replacement "바탕" "Source Han Sans K"
    w_register_font_replacement "바탕체" "Source Han Sans K"
    w_register_font_replacement "돋움" "Source Han Sans K"
    w_register_font_replacement "돋움체" "Source Han Sans K"
    w_register_font_replacement "굴림" "Source Han Sans K"
    w_register_font_replacement "굴림체" "Source Han Sans K"
    w_register_font_replacement "맑은 고딕" "Source Han Sans K"
}

#----------------------------------------------------------------

w_metadata ipamona fonts \
    title="IPAMona Japanese fonts" \
    publisher="Jun Kobayashi" \
    year="2008" \
    media="download" \
    file1="opfc-ModuleHP-1.1.1_withIPAMonaFonts-1.0.8.tar.gz" \
    installed_file1="$W_FONTSDIR_WIN/ipag-mona.ttf" \
    homepage="http://www.geocities.jp/ipa_mona/"

load_ipamona()
{
    w_download "${W_DOWNLOADURLS}/opfc-ModuleHP-1.1.1_withIPAMonaFonts-1.0.8.tar.gz" ab77beea3b051abf606cd8cd3badf6cb24141ef145c60f508fcfef1e3852bb9d

    w_try_cd "$W_TMP"
    w_try tar -zxf "$W_CACHE/$W_PACKAGE/$file1" "${file1%.tar.gz}/fonts"
    w_try_cp_font_files "${file1%.tar.gz}/fonts" "$W_FONTSDIR_UNIX"

    w_register_font ipagui-mona.ttf "IPAMonaUIGothic"
    w_register_font ipag-mona.ttf "IPAMonaGothic"
    w_register_font ipagp-mona.ttf "IPAMonaPGothic"
    w_register_font ipam-mona.ttf "IPAMonaMincho"
    w_register_font ipamp-mona.ttf "IPAMonaPMincho"
}

#----------------------------------------------------------------

w_metadata liberation fonts \
    title="Red Hat Liberation fonts (Mono, Sans, SansNarrow, Serif)" \
    publisher="Red Hat" \
    year="2008" \
    media="download" \
    file1="liberation-fonts-ttf-1.07.4.tar.gz" \
    installed_file1="$W_FONTSDIR_WIN/liberationmono-bolditalic.ttf"

load_liberation()
{
    # https://pagure.io/liberation-fonts
    w_download "${W_DOWNLOADURLS}/liberation-fonts-ttf-1.07.4.tar.gz" 61a7e2b6742a43c73e8762cdfeaf6dfcf9abdd2cfa0b099a9854d69bc4cfee5c

    w_try_cd "$W_TMP"
    w_try tar -zxf "$W_CACHE/$W_PACKAGE/$file1"
    w_try_cp_font_files "${file1%.tar.gz}" "$W_FONTSDIR_UNIX"

    w_register_font liberationmono-bolditalic.ttf "Liberation Mono Bold Italic"
    w_register_font liberationmono-bold.ttf "Liberation Mono Bold"
    w_register_font liberationmono-italic.ttf "Liberation Mono Italic"
    w_register_font liberationmono-regular.ttf "Liberation Mono"

    w_register_font liberationsans-bolditalic.ttf "Liberation Sans Bold Italic"
    w_register_font liberationsans-bold.ttf "Liberation Sans Bold"
    w_register_font liberationsans-italic.ttf "Liberation Sans Italic"
    w_register_font liberationsans-regular.ttf "Liberation Sans"

    w_register_font liberationsansnarrow-bolditalic.ttf "Liberation Sans Narrow Bold Italic"
    w_register_font liberationsansnarrow-bold.ttf "Liberation Sans Narrow Bold"
    w_register_font liberationsansnarrow-italic.ttf "Liberation Sans Narrow Italic"
    w_register_font liberationsansnarrow-regular.ttf "Liberation Sans Narrow"

    w_register_font liberationserif-bolditalic.ttf "Liberation Serif Bold Italic"
    w_register_font liberationserif-bold.ttf "Liberation Serif Bold"
    w_register_font liberationserif-italic.ttf "Liberation Serif Italic"
    w_register_font liberationserif-regular.ttf "Liberation Serif"
}

#----------------------------------------------------------------

w_metadata lucida fonts \
    title="MS Lucida Console font" \
    publisher="Microsoft" \
    year="1998" \
    media="download" \
    file1="eurofixi.exe" \
    installed_file1="$W_FONTSDIR_WIN/lucon.ttf"

load_lucida()
{
    w_download "${W_DOWNLOADURLS}/eurofixi.exe" 41f272a33521f6e15f2cce9ff1e049f2badd5ff0dc327fc81b60825766d5b6c7
    w_try_cabextract -d "$W_TMP" -F "lucon.ttf" "$W_CACHE"/lucida/eurofixi.exe
    w_try_cp_font_files "$W_TMP" "$W_FONTSDIR_UNIX"
    w_register_font lucon.ttf "Lucida Console"
}

#----------------------------------------------------------------

w_metadata opensymbol fonts \
    title="OpenSymbol fonts (replacement for Wingdings)" \
    publisher="OpenOffice.org" \
    year="2017" \
    media="download" \
    file1="fonts-opensymbol_102.10+LibO6.1.5-3+deb10u4_all.deb" \
    installed_file1="$W_FONTSDIR_WIN/opens___.ttf"

load_opensymbol()
{
    # The OpenSymbol fonts are a replacement for the Windows Wingdings font from OpenOffice.org.
    # Need to w_download Debian since I can't find a standalone download from OpenOffice
    # Note: The source download package on debian is for _all_ of OpenOffice, which is 266 MB.
    w_download "${W_DOWNLOADURLS}/fonts-opensymbol_102.10+LibO6.1.5-3+deb10u4_all.deb" 1b2ab1e8eeb9a3a4a07e4a1c9bf539bb721734bf8b9881f4d0b8e71e822cecde
    w_try_cd "$W_TMP"
    w_try_ar "$W_CACHE/$W_PACKAGE/$file1" data.tar.xz
    w_try tar -Jxf "$W_TMP/data.tar.xz" ./usr/share/fonts/truetype/openoffice/opens___.ttf
    w_try_cp_font_files "usr/share/fonts/truetype/openoffice" "$W_FONTSDIR_UNIX"
    w_register_font opens___.ttf "OpenSymbol"
}

#----------------------------------------------------------------

w_metadata sourcehansans fonts \
    title="Source Han Sans fonts" \
    publisher="Adobe" \
    year="2019" \
    media="download" \
    file1="SourceHanSans.ttc" \
    installed_file1="$W_FONTSDIR_WIN/sourcehansans.ttc"

load_sourcehansans()
{
    w_download "${W_DOWNLOADURLS}/SourceHanSans.ttc" 9e94fe493685a7c99ce61e4488169007e3b97badb9f1ef43d3c13da501463780
    w_try cp "$W_CACHE/$W_PACKAGE/$file1" "$W_TMP/sourcehansans.ttc"
    w_try_cp_font_files "$W_TMP" "$W_FONTSDIR_UNIX" "*.ttc"

    # Simplified Chinese
    w_register_font sourcehansans.ttc "Source Han Sans SC ExtraLight"
    w_register_font sourcehansans.ttc "Source Han Sans SC Light"
    w_register_font sourcehansans.ttc "Source Han Sans SC Normal"
    w_register_font sourcehansans.ttc "Source Han Sans SC"
    w_register_font sourcehansans.ttc "Source Han Sans SC Medium"
    w_register_font sourcehansans.ttc "Source Han Sans SC Bold"
    w_register_font sourcehansans.ttc "Source Han Sans SC Heavy"

    # Traditional Chinese (Taiwan)
    w_register_font sourcehansans.ttc "Source Han Sans TC ExtraLight"
    w_register_font sourcehansans.ttc "Source Han Sans TC Light"
    w_register_font sourcehansans.ttc "Source Han Sans TC Normal"
    w_register_font sourcehansans.ttc "Source Han Sans TC"
    w_register_font sourcehansans.ttc "Source Han Sans TC Medium"
    w_register_font sourcehansans.ttc "Source Han Sans TC Bold"
    w_register_font sourcehansans.ttc "Source Han Sans TC Heavy"

    # Japanese
    w_register_font sourcehansans.ttc "Source Han Sans ExtraLight"
    w_register_font sourcehansans.ttc "Source Han Sans Light"
    w_register_font sourcehansans.ttc "Source Han Sans Normal"
    w_register_font sourcehansans.ttc "Source Han Sans"
    w_register_font sourcehansans.ttc "Source Han Sans Medium"
    w_register_font sourcehansans.ttc "Source Han Sans Bold"
    w_register_font sourcehansans.ttc "Source Han Sans Heavy"

    # Korean
    w_register_font sourcehansans.ttc "Source Han Sans K ExtraLight"
    w_register_font sourcehansans.ttc "Source Han Sans K Light"
    w_register_font sourcehansans.ttc "Source Han Sans K Normal"
    w_register_font sourcehansans.ttc "Source Han Sans K"
    w_register_font sourcehansans.ttc "Source Han Sans K Medium"
    w_register_font sourcehansans.ttc "Source Han Sans K Bold"
    w_register_font sourcehansans.ttc "Source Han Sans K Heavy"
}

#----------------------------------------------------------------

w_metadata tahoma fonts \
    title="MS Tahoma font (not part of corefonts)" \
    publisher="Microsoft" \
    year="1999" \
    media="download" \
    file1="IELPKTH.CAB" \
    installed_file1="$W_FONTSDIR_WIN/tahoma.ttf"

load_tahoma()
{
    # Formerly at https://download.microsoft.com/download/ie55sp2/Install/5.5_SP2/WIN98Me/EN-US/IELPKTH.CAB
    w_download ${W_DOWNLOADURLS}/IELPKTH.CAB c1be3fb8f0042570be76ec6daa03a99142c88367c1bc810240b85827c715961a

    w_try_cabextract -d "$W_TMP" "$W_CACHE/$W_PACKAGE/$file1"
    w_try_cp_font_files "$W_TMP" "$W_FONTSDIR_UNIX" "*.TTF"

    w_register_font tahoma.ttf "Tahoma"
    w_register_font tahomabd.ttf "Tahoma Bold"
}

#----------------------------------------------------------------

w_metadata takao fonts \
    title="Takao Japanese fonts" \
    publisher="Jun Kobayashi" \
    year="2010" \
    media="download" \
    file1="takao-fonts-ttf-003.02.01.zip" \
    installed_file1="$W_FONTSDIR_WIN/takaogothic.ttf"

load_takao()
{
    # The Takao font provides Japanese glyphs. May also be needed with fakejapanese function above.
    # See https://launchpad.net/takao-fonts for project page
    w_download "${W_DOWNLOADURLS}/takao-fonts-ttf-003.02.01.zip" 2f526a16c7931958f560697d494d8304949b3ce0aef246fb0c727fbbcc39089e
    w_try_unzip "$W_TMP" "$W_CACHE"/takao/takao-fonts-ttf-003.02.01.zip
    w_try_cp_font_files "$W_TMP/takao-fonts-ttf-003.02.01" "$W_FONTSDIR_UNIX"

    w_register_font takaogothic.ttf "TakaoGothic"
    w_register_font takaopgothic.ttf "TakaoPGothic"
    w_register_font takaomincho.ttf "TakaoMincho"
    w_register_font takaopmincho.ttf "TakaoPMincho"
    w_register_font takaoexgothic.ttf "TakaoExGothic"
    w_register_font takaoexmincho.ttf "TakaoExMincho"
}

#----------------------------------------------------------------

w_metadata uff fonts \
    title="Ubuntu Font Family" \
    publisher="Ubuntu" \
    year="2010" \
    media="download" \
    file1="ubuntu-font-family-0.83.zip" \
    installed_file1="$W_FONTSDIR_WIN/ubuntu-r.ttf" \
    homepage="https://launchpad.net/ubuntu-font-family"

load_uff()
{
    w_download "${W_DOWNLOADURLS}/ubuntu-font-family-0.83.zip" 456d7d42797febd0d7d4cf1b782a2e03680bb4a5ee43cc9d06bda172bac05b42 ubuntu-font-family-0.83.zip
    w_try_unzip "$W_TMP" "$W_CACHE/$W_PACKAGE/$file1"

    w_try_cp_font_files "$W_TMP/$(basename "${file1}" .zip)" "$W_FONTSDIR_UNIX"

    w_register_font ubuntu-bi.ttf "Ubuntu Bold Italic"
    w_register_font ubuntu-b.ttf "Ubuntu Bold"
    w_register_font ubuntu-c.ttf "Ubuntu Condensed"
    w_register_font ubuntu-i.ttf "Ubuntu Italic"
    w_register_font ubuntu-li.ttf "Ubuntu Light Italic"
    w_register_font ubuntu-l.ttf "Ubuntu Light"
    w_register_font ubuntu-mi.ttf "Ubuntu Medium Italic"
    w_register_font ubuntumono-bi.ttf "Ubuntu Mono Bold Italic"
    w_register_font ubuntumono-b.ttf "Ubuntu Mono Bold"
    w_register_font ubuntumono-ri.ttf "Ubuntu Mono Italic"
    w_register_font ubuntumono-r.ttf "Ubuntu Mono"
    w_register_font ubuntu-m.ttf "Ubuntu Medium"
    w_register_font ubuntu-ri.ttf "Ubuntu Italic"
    w_register_font ubuntu-r.ttf "Ubuntu"

}

#----------------------------------------------------------------

w_metadata vlgothic fonts \
    title="VLGothic Japanese fonts" \
    publisher="Project Vine / Daisuke Suzuki" \
    year="2014" \
    media="download" \
    file1="VLGothic-20141206.tar.xz" \
    installed_file1="$W_FONTSDIR_WIN/vl-gothic-regular.ttf" \
    homepage="https://ja.osdn.net/projects/vlgothic"

load_vlgothic()
{
    w_download "${W_DOWNLOADURLS}/VLGothic-20141206.tar.xz" 982040db2f9cb73d7c6ab7d9d163f2ed46d1180f330c9ba2fae303649bf8102d

    w_try_cd "$W_TMP"
    w_try tar -Jxf "$W_CACHE/vlgothic/VLGothic-20141206.tar.xz"
    w_try_cp_font_files "$W_TMP/VLGothic" "$W_FONTSDIR_UNIX"

    w_register_font vl-gothic-regular.ttf "VL Gothic"
    w_register_font vl-pgothic-regular.ttf "VL PGothic"
}

#----------------------------------------------------------------

w_metadata wenquanyi fonts \
    title="WenQuanYi CJK font" \
    publisher="wenq.org" \
    year="2009" \
    media="download" \
    file1="wqy-microhei-0.2.0-beta.tar.gz" \
    installed_file1="$W_FONTSDIR_WIN/wqy-microhei.ttc"

load_wenquanyi()
{
    # See http://wenq.org/enindex.cgi
    # Donate at http://wenq.org/enindex.cgi?Download(en)#MicroHei_Beta if you want to help support free CJK font development
    w_download "${W_DOWNLOADURLS}/wqy-microhei-0.2.0-beta.tar.gz" 2802ac8023aa36a66ea6e7445854e3a078d377ffff42169341bd237871f7213e
    w_try_cd "$W_TMP"
    w_try tar -zxf "$W_CACHE/$W_PACKAGE/$file1"
    w_try_cp_font_files "$W_TMP/wqy-microhei" "$W_FONTSDIR_UNIX" "*.ttc"

    w_register_font wqy-microhei.ttc "WenQuanYi Micro Hei"
}

#----------------------------------------------------------------

w_metadata unifont fonts \
    title="Unifont alternative to Arial Unicode MS" \
    publisher="Roman Czyborra / GNU" \
    year="2019" \
    media="download" \
    file1="unifont-12.1.02.ttf" \
    installed_file1="$W_FONTSDIR_WIN/unifont.ttf"

load_unifont()
{
    # The GNU Unifont provides glyphs for just about everything in common language.  It is intended for multilingual usage.
    # See http://unifoundry.com/unifont.html for project page
    w_download "${W_DOWNLOADURLS}/unifont-12.1.02.ttf" da4961540b9d02e01fb8755924db730db233c360b20ee321fda8ab7d0b9ca549
    w_try cp "$W_CACHE/$W_PACKAGE/$file1" "$W_TMP/unifont.ttf"
    w_try_cp_font_files "$W_TMP" "$W_FONTSDIR_UNIX"

    w_register_font unifont.ttf "Unifont"
    w_register_font_replacement "Arial Unicode MS" "Unifont"
}

#----------------------------------------------------------------

w_metadata allfonts fonts \
    title="All fonts" \
    publisher="various" \
    year="1998-2010" \
    media="download"

load_allfonts()
{
    # This verb uses reflection, should probably do it portably instead, but that would require keeping it up to date
    for file in "$WINETRICKS_METADATA"/fonts/*.vars; do
        cmd=$(basename "$file" .vars)
        case $cmd in
            # "fake*" verbs need to be skipped because
            # this "allfonts" verb is intended to only install real fonts and
            # adding font replacements at the same time may invalidate the replacements
            # "pptfonts" can be skipped because it only calls other verbs for installing fonts
            # See https://github.com/Winetricks/winetricks/issues/899
            allfonts|cjkfonts|fake*|pptfonts) ;;
            *) w_call "$cmd";;
        esac
    done
}

#----------------------------------------------------------------
# Mac Driver settings

w_metadata macdriver=mac settings \
    title_uk="Увімкнути рідний Mac Quartz драйвер (за замовчуванням)" \
    title="Enable the Mac native Quartz driver (default)"
w_metadata macdriver=x11 settings \
    title_uk="Вимкнути рідний Mac Quartz драйвер та використовувати замість нього X11" \
    title="Disable the Mac native Quartz driver, use X11 instead"

load_macdriver()
{
    echo "Setting MacDriver to $arg"
    cat > "$W_TMP"/set-mac.reg <<_EOF_
REGEDIT4

[HKEY_CURRENT_USER\\Software\\Wine\\Drivers]
"Graphics"="$arg"

_EOF_
    w_try_regedit "$W_TMP"/set-mac.reg
}

#----------------------------------------------------------------

w_metadata mackeyremap=both settings \
    title="Enable mapping opt->alt and cmd->ctrl keys for the Mac native driver"
w_metadata mackeyremap=left settings \
    title="Enable mapping of left opt->alt and cmd->ctrl keys for the Mac native driver"
w_metadata mackeyremap=none settings \
    title="Do not remap keys for the Mac native driver (default)"

load_mackeyremap()
{
    case "$1" in
        both|y) arg=both; _W_arg_l=y; _W_arg_r=y ;;
        left)   arg=left; _W_arg_l=y; _W_arg_r=n ;;
        none|n) arg=none; _W_arg_l=n; _W_arg_r=n ;;
        *) w_die "illegal value $1 for MacKeyRemap";;
    esac

    echo "Setting MacKeyRemap to $arg"
    cat > "$W_TMP"/set-mackeyremap.reg <<_EOF_
REGEDIT4

[HKEY_CURRENT_USER\\Software\\Wine\\Mac Driver]
"LeftCommandIsCtrl"="$_W_arg_l"
"LeftOptionIsAlt"="$_W_arg_l"
"RightCommandIsCtrl"="$_W_arg_r"
"RightOptionIsAlt"="$_W_arg_r"

_EOF_
    w_try_regedit "$W_TMP"/set-mackeyremap.reg

    unset _W_arg_l _W_arg_r
}

#----------------------------------------------------------------
# X11 Driver settings

w_metadata grabfullscreen=y settings \
    title_uk="Примусове захоплення курсору для повноекранних вікон (необхідно для деяких ігор)" \
    title="Force cursor clipping for full-screen windows (needed by some games)"
w_metadata grabfullscreen=n settings \
    title_uk="Вимкнути примусове захоплення курсору для повноекранних вікон (за замовчуванням)" \
    title="Disable cursor clipping for full-screen windows (default)"

load_grabfullscreen()
{
    case "$1" in
        y|n) arg=$1;;
        *) w_die "illegal value $1 for GrabFullscreen";;
    esac

    echo "Setting GrabFullscreen to $arg"
    cat > "$W_TMP"/set-gfs.reg <<_EOF_
REGEDIT4

[HKEY_CURRENT_USER\\Software\\Wine\\X11 Driver]
"GrabFullscreen"="$arg"

_EOF_
    w_try_regedit "$W_TMP"/set-gfs.reg
}

w_metadata windowmanagerdecorated=y settings \
    title_uk="Дозволити менеджеру вікон декорувати вікна (за замовчуванням)" \
    title="Allow the window manager to decorate windows (default)"
w_metadata windowmanagerdecorated=n settings \
    title_uk="Не дозволяти менеджеру вікон декорувати вікна" \
    title="Prevent the window manager from decorating windows"

#----------------------------------------------------------------

w_metadata usetakefocus=enabled settings \
    title_cz="Aktivovat UseTakeFocus" \
    title_uk="Увімкнути фокусування на вікні" \
    title_sk="Aktivovať UseTakeFocus" \
    title_tlh="Qorwagh buSchoH \'e\' chu\'" \
    title="Enable UseTakeFocus"
w_metadata usetakefocus=disabled settings \
    title_cz="Deaktivovat UseTakeFocus (výchozí)" \
    title_uk="Вимкнути фокусування на вікні (за замовчуванням)" \
    title_sk="Deaktivovať UseTakeFocus (výchozí)" \
    title_tlh="Qorwagh buSchoH \'e\' chu\'Ha\' (DuH choHlu\'pu\'be\'bogh)" \
    title="Disable UseTakeFocus (default)"

load_usetakefocus()
{
    case "$1" in
        enabled) arg="Y";;
        disabled) arg="N";;
        *) w_die "illegal value $1 for UseTakeFocus";;
    esac

    echo "Setting UseTakeFocus to $arg"
    cat > "$W_TMP"/set-gfs.reg <<_EOF_
REGEDIT4

[HKEY_CURRENT_USER\\Software\\Wine\\X11 Driver]
"UseTakeFocus"="$arg"

_EOF_
    w_try_regedit "$W_TMP"/set-gfs.reg
}

#----------------------------------------------------------------

load_windowmanagerdecorated()
{
    case "$1" in
        y|n) arg=$1;;
        *) w_die "illegal value $1 for Decorated";;
    esac

    echo "Setting Decorated to $arg"
    cat > "$W_TMP"/set-wmd.reg <<_EOF_
REGEDIT4

[HKEY_CURRENT_USER\\Software\\Wine\\X11 Driver]
"Decorated"="$arg"

_EOF_
    w_try_regedit "$W_TMP"/set-wmd.reg
}

w_metadata windowmanagermanaged=y settings \
    title_uk="Дозволити менеджеру вікон керування вікнами (за замовчуванням)" \
    title="Allow the window manager to control windows (default)"
w_metadata windowmanagermanaged=n settings \
    title_uk="Не дозволяти менеджеру вікон керування вікнами" \
    title="Prevent the window manager from controlling windows"

#----------------------------------------------------------------

load_windowmanagermanaged()
{
    case "$1" in
        y|n) arg=$1;;
        *) w_die "illegal value $1 for Managed";;
    esac

    echo "Setting Managed to $arg"
    cat > "$W_TMP"/set-wmm.reg <<_EOF_
REGEDIT4

[HKEY_CURRENT_USER\\Software\\Wine\\X11 Driver]
"Managed"="$arg"

_EOF_
    w_try_regedit "$W_TMP"/set-wmm.reg
}

#----------------------------------------------------------------

w_metadata vd=off settings \
    title_uk="Вимкнути віртуальний робочий стіл" \
    title="Disable virtual desktop"
w_metadata vd=640x480 settings \
    title_uk="Увімкнути віртуальний робочий стіл та встановити розмір 640x480" \
    title="Enable virtual desktop, set size to 640x480"
w_metadata vd=800x600 settings \
    title_uk="Увімкнути віртуальний робочий стіл та встановити розмір 800x600" \
    title="Enable virtual desktop, set size to 800x600"
w_metadata vd=1024x768 settings \
    title_uk="Увімкнути віртуальний робочий стіл та встановити розмір 1024x768" \
    title="Enable virtual desktop, set size to 1024x768"
w_metadata vd=1280x1024 settings \
    title_uk="Увімкнути віртуальний робочий стіл та встановити розмір 1280x1024" \
    title="Enable virtual desktop, set size to 1280x1024"
w_metadata vd=1440x900 settings \
    title_uk="Увімкнути віртуальний робочий стіл та встановити розмір 1440x900" \
    title="Enable virtual desktop, set size to 1440x900"

load_vd()
{
    size="$1"
    case $size in
        off|disabled)
        cat > "$W_TMP"/vd.reg <<_EOF_
REGEDIT4

[HKEY_CURRENT_USER\\Software\\Wine\\Explorer]
"Desktop"=-
[HKEY_CURRENT_USER\\Software\\Wine\\Explorer\\Desktops]
"Default"=-

_EOF_
        ;;
        [1-9]*x[1-9]*)
        cat > "$W_TMP"/vd.reg <<_EOF_
REGEDIT4

[HKEY_CURRENT_USER\\Software\\Wine\\Explorer]
"Desktop"="Default"
[HKEY_CURRENT_USER\\Software\\Wine\\Explorer\\Desktops]
"Default"="$size"

_EOF_
        ;;
        *)
        w_die "you want a virtual desktop of $size? I don't understand."
        ;;
    esac
    w_try_regedit "$W_TMP_WIN"/vd.reg
}

#----------------------------------------------------------------
# MIME-type file associations settings

w_metadata mimeassoc=on settings \
    title="Enable exporting MIME-type file associations to the native desktop (default)"
w_metadata mimeassoc=off settings \
    title="Disable exporting MIME-type file associations to the native desktop"

load_mimeassoc()
{
    case "$1" in
        off) arg=N;;
        on)  arg=Y;;
        *) w_die "illegal value $1 for mimeassoc";;
    esac

    echo "Setting mimeassoc to $arg"
    cat > "$W_TMP"/set-mimeassoc.reg <<_EOF_
REGEDIT4

[HKEY_CURRENT_USER\\Software\\Wine\\FileOpenAssociations]
"Enable"="$arg"

_EOF_
    w_try_regedit "$W_TMP"/set-mimeassoc.reg
}

####
# settings->direct3d

winetricks_set_wined3d_var()
{
    # Filter out/correct bad or partial values
    # Confusing because dinput uses 'disable', but d3d uses 'disabled'
    # see wined3d_dll_init() in dlls/wined3d/wined3d_main.c
    # and DllMain() in dlls/ddraw/main.c
    case $2 in
        disable*) arg=disabled;;
        enable*) arg=enabled;;
        hard*) arg=hardware;;
        repack) arg=repack;;
        backbuffer|fbo|gdi|none|opengl|readdraw|readtex|texdraw|textex|auto) arg=$2;;
        [0-9]*) arg=$2;;
        *) w_die "illegal value $2 for $1";;
    esac

    echo "Setting Direct3D/$1 to $arg"
    cat > "$W_TMP"/set-wined3d.reg <<_EOF_
REGEDIT4

[HKEY_CURRENT_USER\\Software\\Wine\\Direct3D]
"$1"="$arg"

_EOF_
    w_try_regedit "$W_TMP_WIN"\\set-wined3d.reg
}

#----------------------------------------------------------------
# AlwaysOffscreen settings

w_metadata ao=enabled settings \
    title_uk="Увімкнути AlwaysOffscreen" \
    title="Enable AlwaysOffscreen"
w_metadata ao=disabled settings \
    title_uk="Вимкнути AlwaysOffscreen (за замовчуванням)" \
    title="Disable AlwaysOffscreen (default)"

load_ao()
{
    winetricks_set_wined3d_var AlwaysOffscreen "$1"
}

#----------------------------------------------------------------
# CheckFloatConstants settings

w_metadata cfc=enabled settings \
    title_uk="Увімкнути CheckFloatConstants" \
    title="Enable CheckFloatConstants"
w_metadata cfc=disable settings \
    title_uk="Вимкнути CheckFloatConstants (за замовчуванням)" \
    title="Disable CheckFloatConstants (default)"

load_cfc()
{
    winetricks_set_wined3d_var CheckFloatConstants "$1"
}
#----------------------------------------------------------------
# CSMT settings

w_metadata csmt=on settings \
    title_uk="Увімкнути Command Stream Multithreading (за замовчуванням)" \
    title="Enable Command Stream Multithreading (default)"
w_metadata csmt=off settings \
    title_uk="Вимкнути Command Stream Multithreading"\
    title="Disable Command Stream Multithreading"

load_csmt()
{
    case "$1" in
        off) arg=0;;
        on)  arg=1;;
        *) w_die "illegal value $1 for csmt";;
    esac

    echo "Setting csmt to $arg"
    cat > "$W_TMP"/set-csmt.reg <<_EOF_
REGEDIT4

[HKEY_CURRENT_USER\\Software\\Wine\\Direct3D]
"csmt"=dword:$arg

_EOF_
    w_try_regedit "$W_TMP"/set-csmt.reg
}

#----------------------------------------------------------------
# DirectDraw settings

w_metadata ddr=gdi settings \
    title_uk="Встановити DirectDrawRenderer на gdi" \
    title="Set DirectDrawRenderer to gdi"
w_metadata ddr=opengl settings \
    title_uk="Встановити DirectDrawRenderer на opengl" \
    title="Set DirectDrawRenderer to opengl"

load_ddr()
{
    winetricks_set_wined3d_var DirectDrawRenderer "$1"
}

#----------------------------------------------------------------

w_metadata glsl=enabled settings \
    title_uk="Увімкнути GLSL шейдери (за замовчуванням)" \
    title="Enable GLSL shaders (default)"
w_metadata glsl=disabled settings \
    title_uk="Вимкнути GLSL шейдери та використовувати ARB шейдери (іноді впливає на швидкодію)" \
    title="Disable GLSL shaders, use ARB shaders (faster, but sometimes breaks)"

load_glsl()
{
    winetricks_set_wined3d_var UseGLSL "$1"
}

#----------------------------------------------------------------

w_metadata gsm=0 settings \
    title_uk="Встановити MaxShaderModelGS на 0" \
    title="Set MaxShaderModelGS to 0"
w_metadata gsm=1 settings \
    title_uk="Встановити MaxShaderModelGS на 1" \
    title="Set MaxShaderModelGS to 1"
w_metadata gsm=2 settings \
    title_uk="Встановити MaxShaderModelGS на 2" \
    title="Set MaxShaderModelGS to 2"
w_metadata gsm=3 settings \
    title_uk="Встановити MaxShaderModelGS на 3" \
    title="Set MaxShaderModelGS to 3"

load_gsm()
{
    winetricks_set_wined3d_var MaxShaderModelGS "$1"
}

#----------------------------------------------------------------

w_metadata multisampling=enabled settings \
    title_uk="Увімкнути Direct3D мультисемплінг" \
    title="Enable Direct3D multisampling"
w_metadata multisampling=disabled settings \
    title_uk="Вимкнути Direct3D мультисемплінг" \
    title="Disable Direct3D multisampling"

load_multisampling()
{
    winetricks_set_wined3d_var Multisampling "$1"
}

#----------------------------------------------------------------

w_metadata npm=repack settings \
    title_uk="Встановити NonPower2Mode на repack" \
    title="Set NonPower2Mode to repack"

load_npm()
{
    winetricks_set_wined3d_var NonPower2Mode "$1"
}

#----------------------------------------------------------------

w_metadata orm=fbo settings \
    title_uk="Встановити OffscreenRenderingMode=fbo (за замовчуванням)" \
    title="Set OffscreenRenderingMode=fbo (default)"
w_metadata orm=backbuffer settings \
    title_uk="Встановити OffscreenRenderingMode=backbuffer" \
    title="Set OffscreenRenderingMode=backbuffer"

load_orm()
{
    winetricks_set_wined3d_var OffscreenRenderingMode "$1"
}

#----------------------------------------------------------------

w_metadata psm=0 settings \
    title_uk="Встановити MaxShaderModelPS на 0" \
    title="Set MaxShaderModelPS to 0"
w_metadata psm=1 settings \
    title_uk="Встановити MaxShaderModelPS на 1" \
    title="Set MaxShaderModelPS to 1"
w_metadata psm=2 settings \
    title_uk="Встановити MaxShaderModelPS на 2" \
    title="Set MaxShaderModelPS to 2"
w_metadata psm=3 settings \
    title_uk="Встановити MaxShaderModelPS на 3" \
    title="Set MaxShaderModelPS to 3"

load_psm()
{
    winetricks_set_wined3d_var MaxShaderModelPS "$1"
}

#----------------------------------------------------------------

w_metadata strictdrawordering=enabled settings \
    title_uk="Увімкнути StrictDrawOrdering" \
    title="Enable StrictDrawOrdering"
w_metadata strictdrawordering=disabled settings \
    title_uk="Вимкнути StrictDrawOrdering (за замовчуванням)" \
    title="Disable StrictDrawOrdering (default)"

load_strictdrawordering()
{
    winetricks_set_wined3d_var StrictDrawOrdering "$1"
}

#----------------------------------------------------------------

w_metadata rtlm=auto settings \
    title_uk="Встановити RenderTargetLockMode на авто (за замовчуванням)" \
    title="Set RenderTargetLockMode to auto (default)"
w_metadata rtlm=disabled settings \
    title_uk="Вимкнути RenderTargetLockMode" \
    title="Set RenderTargetLockMode to disabled"
w_metadata rtlm=readdraw settings \
    title_uk="Встановити RenderTargetLockMode на readdraw" \
    title="Set RenderTargetLockMode to readdraw"
w_metadata rtlm=readtex settings \
    title_uk="Встановити RenderTargetLockMode на readtex" \
    title="Set RenderTargetLockMode to readtex"
w_metadata rtlm=texdraw settings \
    title_uk="Встановити RenderTargetLockMode на texdraw" \
    title="Set RenderTargetLockMode to texdraw"
w_metadata rtlm=textex settings \
    title_uk="Встановити RenderTargetLockMode на textex" \
    title="Set RenderTargetLockMode to textex"

load_rtlm()
{
    winetricks_set_wined3d_var RenderTargetLockMode "$1"
}
#----------------------------------------------------------------

w_metadata videomemorysize=default settings \
    title_uk="Дати можливість Wine визначити розмір відеопам'яті" \
    title="Let Wine detect amount of video card memory"
w_metadata videomemorysize=512 settings \
    title_uk="Повідомити Wine про 512МБ відеопам'яті" \
    title="Tell Wine your video card has 512MB RAM"
w_metadata videomemorysize=1024 settings \
    title_uk="Повідомити Wine про 1024МБ відеопам'яті" \
    title="Tell Wine your video card has 1024MB RAM"
w_metadata videomemorysize=2048 settings \
    title_uk="Повідомити Wine про 2048МБ відеопам'яті" \
    title="Tell Wine your video card has 2048MB RAM"

load_videomemorysize()
{
    size="$1"
    echo "Setting video memory size to $size"

    case $size in
        default)

    cat > "$W_TMP"/set-video.reg <<_EOF_
REGEDIT4

[HKEY_CURRENT_USER\\Software\\Wine\\Direct3D]
"VideoMemorySize"=-

_EOF_
    ;;
        *)
    cat > "$W_TMP"/set-video.reg <<_EOF_
REGEDIT4

[HKEY_CURRENT_USER\\Software\\Wine\\Direct3D]
"VideoMemorySize"="$size"

_EOF_
    ;;
    esac
    w_try_regedit "$W_TMP_WIN"\\set-video.reg
}

#----------------------------------------------------------------

w_metadata vsm=0 settings \
    title_uk="Встановити MaxShaderModelVS на 0" \
    title="Set MaxShaderModelVS to 0"
w_metadata vsm=1 settings \
    title_uk="Встановити MaxShaderModelVS на 1" \
    title="Set MaxShaderModelVS to 1"
w_metadata vsm=2 settings \
    title_uk="Встановити MaxShaderModelVS на 2" \
    title="Set MaxShaderModelVS to 2"
w_metadata vsm=3 settings \
    title_uk="Встановити MaxShaderModelVS на 3" \
    title="Set MaxShaderModelVS to 3"

load_vsm()
{
    winetricks_set_wined3d_var MaxShaderModelVS "$1"
}

####
# settings->debug

#----------------------------------------------------------------

w_metadata autostart_winedbg=enabled settings \
    title="Automatically launch winedbg when an unhandled exception occurs (default)"
w_metadata autostart_winedbg=disabled settings \
    title="Prevent winedbg from launching when an unhandled exception occurs"

load_autostart_winedbg()
{
    case "$arg" in
        # accidentally commited as enable/disable, so accept that, but prefer enabled/disabled
        enable|enabled) _W_debugger_value="winedbg --auto %ld %ld";;
        disable|disabled) _W_debugger_value="false";;
        *) w_die "Unexpected argument '$arg'. Should be enable/disable";;
    esac

    echo "Setting HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\Debugger to '$arg'"
    cat > "$W_TMP"/autostart_winedbg.reg <<_EOF_
REGEDIT4

[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug]
"Debugger"="${_W_debugger_value}"
_EOF_

    w_try_regedit "$W_TMP_WIN"\\autostart_winedbg.reg
    w_backup_reg_file "$W_TMP"/autostart_winedbg.reg

    unset _W_debugger_value
}

#----------------------------------------------------------------

w_metadata heapcheck settings \
    title_uk="Увімкнути накопичувальну перевірку GlobalFlag" \
    title="Enable heap checking with GlobalFlag"

load_heapcheck()
{
    cat > "$W_TMP"/heapcheck.reg <<_EOF_
REGEDIT4

[HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager]
"GlobalFlag"=dword:00200030

_EOF_
    w_try_regedit "$W_TMP_WIN"\\heapcheck.reg
}

#----------------------------------------------------------------

w_metadata nocrashdialog settings \
    title_uk="Вимкнути діалог про помилку" \
    title="Disable crash dialog"

load_nocrashdialog()
{
    echo "Disabling graphical crash dialog"
    cat > "$W_TMP"/crashdialog.reg <<_EOF_
REGEDIT4

[HKEY_CURRENT_USER\\Software\\Wine\\WineDbg]
"ShowCrashDialog"=dword:00000000

_EOF_
    w_try_cd "$W_TMP"
    w_try_regedit crashdialog.reg
}

####
# settings->misc

w_metadata alldlls=default settings \
    title_uk="Видалити всі перевизначення DLL" \
    title="Remove all DLL overrides"
w_metadata alldlls=builtin settings \
    title_uk="Перевизначити найбільш поширені DLL на вбудовані" \
    title="Override most common DLLs to builtin"

load_alldlls()
{
    case "$1" in
        default) w_override_no_dlls ;;
        builtin) w_override_all_dlls ;;
    esac
}

#----------------------------------------------------------------

w_metadata bad settings \
    title="Fake verb that always returns false"

load_bad()
{
    w_die "$W_PACKAGE failed!"
}

#----------------------------------------------------------------

w_metadata forcemono settings \
    title_uk="Примусове використання mono замість .NET (для налагодження)" \
    title="Force using Mono instead of .NET (for debugging)"

load_forcemono()
{
    w_override_dlls native mscoree
    w_override_dlls disabled mscorsvw.exe
}

#----------------------------------------------------------------

w_metadata good settings \
    title="Fake verb that always returns true"

load_good()
{
    w_info "$W_PACKAGE succeeded!"
}

#----------------------------------------------------------------

w_metadata hidewineexports=enable settings \
    title="Enable hiding Wine exports from applications (wine-staging)"
w_metadata hidewineexports=disable settings \
    title="Disable hiding Wine exports from applications (wine-staging)"

load_hidewineexports()
{
    # Wine exports some functions allowing apps to query the Wine version and
    # information about the host environment. Using these functions, some apps
    # will intentionally terminate if they can detect that they are running in
    # a Wine environment.
    #
    # Hiding these Wine exports is only available in wine-staging.
    # See https://bugs.winehq.org/show_bug.cgi?id=38656
    case $arg in
        enable)
            _W_registry_value="\"Y\""
            ;;
        disable)
            _W_registry_value="-"
            ;;
        *) w_die "Unexpected argument, $arg";;
    esac

    cat > "$W_TMP"/set-wineexports.reg <<_EOF_
REGEDIT4

[HKEY_CURRENT_USER\\Software\\Wine]
"HideWineExports"=$_W_registry_value

_EOF_
    w_try_regedit "$W_TMP"/set-wineexports.reg
}

#----------------------------------------------------------------

w_metadata hosts settings \
    title_uk="Додати порожні файли у C:\\windows\\system32\\drivers\\etc\\{hosts,services}" \
    title="Add empty C:\\windows\\system32\\drivers\\etc\\{hosts,services} files"

load_hosts()
{
    # Create fake system32\drivers\etc\hosts and system32\drivers\etc\services files.
    # The hosts file is used to map network names to IP addresses without DNS.
    # The services file is used map service names to network ports.
    # Some apps depend on these files, but they're not implemented in Wine.
    # Fortunately, empty files in the correct location satisfy those apps.
    # See https://bugs.winehq.org/show_bug.cgi?id=12076

    # It's in system32 for both win32/win64
    mkdir -p "$W_WINDIR_UNIX"/system32/drivers/etc
    touch "$W_WINDIR_UNIX"/system32/drivers/etc/hosts
    touch "$W_WINDIR_UNIX"/system32/drivers/etc/services
}

#----------------------------------------------------------------

w_metadata isolate_home settings \
    title_uk="Видалити посилання на вино преміум на \$HOME" \
    title="Remove wineprefix links to \$HOME"

load_isolate_home()
{
    w_skip_windows isolate_home && return

    _olddir="$(pwd)"
    w_try_cd "$WINEPREFIX/drive_c/users/$USER"
    for x in *; do
        if test -h "$x" && test -d "$x"; then
            rm -f "$x"
            mkdir -p "$x"
        fi
    done
    w_try_cd "$_olddir"
    unset _olddir

    # Workaround for:
    # https://bugs.winehq.org/show_bug.cgi?id=22450 (sandbox verb)
    # https://bugs.winehq.org/show_bug.cgi?id=22974 (isolate_home, sandbox verbs)
    echo disable > "$WINEPREFIX/.update-timestamp"
}

#----------------------------------------------------------------

w_metadata native_mdac settings \
    title_uk="Перевизначити odbc32, odbccp32 та oledb32" \
    title="Override odbc32, odbccp32 and oledb32"

load_native_mdac()
{
    # Set those overrides globally so user programs get MDAC's ODBC
    # instead of Wine's unixodbc

    # https://github.com/Winetricks/winetricks/issues/1447
    if w_wine_version_in 4.22, ; then
        w_override_dlls native,builtin msado15
    fi

    # https://github.com/Winetricks/winetricks/issues/1448
    if w_wine_version_in ,4.22 ; then
        w_override_dlls native,builtin odbccp32
    fi

    w_override_dlls native,builtin mtxdm odbc32 oledb32
}

#----------------------------------------------------------------

w_metadata native_oleaut32 settings \
    title_uk="Перевизначити oleaut32" \
    title="Override oleaut32"

load_native_oleaut32()
{
    w_override_dlls native,builtin oleaut32
}

#----------------------------------------------------------------

w_metadata remove_mono settings \
    title_uk="Видалити вбудоване wine-mono" \
    title="Remove builtin wine-mono"

load_remove_mono()
{
    # Wine before 4.6 installs 'Wine Mono'
    # Beginning in 4.6, if using a shared install (i.e., a distro mono package or a tarball manually
    # extracted to /usr/share/wine/mono, or equivalent), only 'Wine Mono Windows Support' will be installed.
    # If using the old .msi installer, *both* tarballs are installed.
    #
    # So, we uninstall anything that has 'Wine Mono' in the name to handle both cases.
    # If wine uninstaller can't find the application it will return 0 anyway.
    mono_uuid="$("${WINE_ARCH}" uninstaller --list | grep 'Wine Mono' | cut -f1 -d\|)"
    if test "$mono_uuid"; then
        for uuid in $mono_uuid; do
            "${WINE_ARCH}" uninstaller --remove "$uuid"
        done
    else
        # Bail out if mono isn't installed, so we don't break .Net setups
        w_warn "Mono does not appear to be installed."
        return
    fi

    # FIXME: verify on pristine Windows XP:
    if w_workaround_wine_bug 34803; then
        "${WINE_ARCH}" reg delete 'HKLM\\Software\\Microsoft\\.NETFramework\\v2.0.50727\\SBSDisabled' /f
    fi

    "${WINE_ARCH}" reg delete "HKLM\\Software\\Microsoft\\NET Framework Setup\\NDP\\v3.5" /f || true
    "${WINE_ARCH}" reg delete "HKLM\\Software\\Microsoft\\NET Framework Setup\\NDP\\v4" /f || true

    w_try rm -f "$W_WINDIR_UNIX/system32/mscoree.dll"
    if [ "$W_ARCH" = "win64" ]; then
        w_try rm -f "$W_WINDIR_UNIX/syswow64/mscoree.dll"
    fi
}


#----------------------------------------------------------------

w_metadata sandbox settings \
    title_uk="Пісочниця wineprefix - видалити посилання до HOME" \
    title="Sandbox the wineprefix - remove links to \$HOME"

load_sandbox()
{
    w_skip_windows sandbox && return

    # Unmap drive Z
    rm -f "$WINEPREFIX/dosdevices/z:"

    # Disable unixfs
    # Unfortunately, when you run with a different version of Wine, Wine will recreate this key.
    # See https://bugs.winehq.org/show_bug.cgi?id=22450
    w_try_regedit /D "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Desktop\\Namespace\\{9D20AAE8-0625-44B0-9CA7-71889C2254D9}"

    w_call isolate_home
}

####
# settings->sound

#----------------------------------------------------------------

w_metadata sound=alsa settings \
    title_uk="Встановити звуковий драйвер ALSA" \
    title="Set sound driver to ALSA"
w_metadata sound=coreaudio settings \
    title_uk="Встановити звуковий драйвер Mac CoreAudio" \
    title="Set sound driver to Mac CoreAudio"
w_metadata sound=disabled settings \
    title_uk="Вимкнути звуковий драйвер" \
    title="Set sound driver to disabled"
w_metadata sound=oss settings \
    title_uk="Встановити звуковий драйвер OSS" \
    title="Set sound driver to OSS"
w_metadata sound=pulse settings \
    title_uk="Встановити звуковий драйвер PulseAudio" \
    title="Set sound driver to PulseAudio"

load_sound()
{
    echo "Setting sound driver to $1"
    cat > "$W_TMP"/set-sound.reg <<_EOF_
REGEDIT4

[HKEY_CURRENT_USER\\Software\\Wine\\Drivers]
"Audio"="$1"

_EOF_
    w_try_regedit "$W_TMP_WIN"\\set-sound.reg
}

# settings->winversions
#----------------------------------------------------------------

w_metadata nt40 settings \
    title_uk="Встановити версію Windows NT 4.0" \
    title="Set windows version to Windows NT 4.0"

load_nt40()
{
    w_set_winver nt40
}

#----------------------------------------------------------------

w_metadata vista settings \
    title_uk="Встановити версію Windows Vista" \
    title="Set Windows version to Windows Vista"

load_vista()
{
    w_set_winver vista
}

#----------------------------------------------------------------

w_metadata win2k settings \
    title_uk="Встановити версію Windows 2000" \
    title="Set Windows version to Windows 2000"

load_win2k()
{
    w_set_winver win2k
}

#----------------------------------------------------------------

w_metadata win2k3 settings \
    title_uk="Встановити версію Windows 2003" \
    title="Set Windows version to Windows 2003"

load_win2k3()
{
    w_set_winver win2k3
}

#----------------------------------------------------------------

w_metadata win2k8 settings \
    title_uk="Встановити версію Windows 2008" \
    title="Set Windows version to Windows 2008"

load_win2k8()
{
    w_set_winver win2k8
}

#----------------------------------------------------------------

w_metadata win2k8r2 settings \
    title_uk="Встановити версію Windows 2008 R2" \
    title="Set Windows version to Windows 2008 R2"

load_win2k8r2()
{
    w_set_winver win2k8r2
}

#----------------------------------------------------------------

w_metadata win31 settings \
    title_uk="Встановити версію Windows 3.1" \
    title="Set Windows version to Windows 3.1"

load_win31()
{
    w_set_winver win31
}

#----------------------------------------------------------------

w_metadata win7 settings \
    title_uk="Встановити версію Windows 7" \
    title="Set Windows version to Windows 7"

load_win7()
{
    w_set_winver win7
}

#----------------------------------------------------------------

w_metadata win8 settings \
    title_uk="Встановити версію Windows 8" \
    title="Set Windows version to Windows 8"

load_win8()
{
    w_set_winver win8
}

#----------------------------------------------------------------

w_metadata win81 settings \
    title_uk="Встановити версію Windows 8.1" \
    title="Set Windows version to Windows 8.1"

load_win81()
{
    w_set_winver win81
}

#----------------------------------------------------------------

w_metadata win10 settings \
    title_uk="Встановити версію Windows 10" \
    title="Set Windows version to Windows 10"

load_win10()
{
    w_set_winver win10
}

#----------------------------------------------------------------

w_metadata win95 settings \
    title_uk="Встановити версію Windows 95" \
    title="Set Windows version to Windows 95"

load_win95()
{
    w_set_winver win95
}

#----------------------------------------------------------------

w_metadata win98 settings \
    title_uk="Встановити версію Windows 98" \
    title="Set Windows version to Windows 98"

load_win98()
{
    w_set_winver win98
}

#----------------------------------------------------------------

# Really, we should support other values, since winetricks did
w_metadata winver= settings \
    title_uk="Встановити версію Windows за замовчуванням (Windows 7)" \
    title="Set Windows version to default (win7)"

load_winver()
{
    w_set_winver win7
}

#----------------------------------------------------------------

w_metadata winxp settings \
    title_uk="Встановити версію Windows XP" \
    title="Set Windows version to Windows XP"

load_winxp()
{
    w_set_winver winxp
}

#---- Main Program ----

winetricks_stats_save()
{
    # Save opt-in status
    if test "$WINETRICKS_STATS_REPORT"; then
        if test ! -d "$W_CACHE"; then
            mkdir -p "$W_CACHE"
        fi
        echo "$WINETRICKS_STATS_REPORT" > "$W_CACHE"/track_usage
    fi
}

winetricks_stats_init()
{
    # Load opt-in status if not already set by a command-line option
    if test ! "$WINETRICKS_STATS_REPORT" && test -f "$W_CACHE"/track_usage; then
        WINETRICKS_STATS_REPORT=$(cat "$W_CACHE"/track_usage)
    fi

    if test ! "$WINETRICKS_STATS_REPORT"; then
        # No opt-in status found.  If GUI active, ask user whether they would like to opt in.
        case $WINETRICKS_GUI in
            zenity)
                case $LANG in
                de*)
                    title="Einmalige Frage zur Hilfe an der Winetricks Entwicklung"
                    question="Möchten Sie die Winetricks Entwicklung unterstützen indem Sie Winetricks Statistiken übermitteln lassen? Sie können die Übermittlung jederzeit mit 'winetricks --optout' ausschalten"
                    thanks="Danke! Sie bekommen diese Frage nicht mehr gestellt. Sie können die Übermittlung jederzeit mit 'winetricks --optout' wieder ausschalten"
                    declined="OK, Winetricks wird *keine* Statistiken übermitteln. Sie bekommen diese Frage nicht mehr gestellt."
                    ;;
                pl*)
                    title="Jednorazowe pytanie dotyczące pomocy w rozwoju Winetricks"
                    question="Czy chcesz pomóc w rozwoju Winetricks pozwalając na wysyłanie statystyk przez program? Możesz wyłączyć tą opcję w każdej chwili z użyciem komendy 'winetricks --optout'."
                    thanks="Dziękujemy! Nie otrzymasz już tego pytania. Pamiętaj, ze możesz wyłączyć tą opcję komendą 'winetricks --optout'"
                    declined="OK, Winetricks *nie* będzie wysyłać statystyk. Nie otrzymasz już tego pytania."
                    ;;
                ru*)
                    title="Помощь в разработке Winetricks"
                    question="Вы хотите помочь разработке winetricks, отправляя статистику? Вы можете отключить отправку статистики в любое время с помощью команды 'winetricks --optout'"
                    thanks="Спасибо! Этот вопрос больше не появится. Помните: вы можете отключить отправку статистики в любое время с помощью команды 'winetricks --optout'"
                    declined="OK, winetricks НЕ будет отправлять статистику. Этот вопрос больше не появится."
                    ;;
                uk*)
                    title="Допомога в розробці Winetricks"
                    question="Ви хочете допомогти в розробці Winetricks дозволивши звітувати статистику?\\nВи можете в будь-який час вимкнути цю опцію за допомогою команди 'winetricks --optout'"
                    thanks="Дякуємо! Ви більше не отримуватиме це питання знову. Пам'ятайте, що ви можете будь-коли вимкнути звітність за допомогою команди 'winetricks --optout'"
                    declined="Надсилання звітності Winetricks вимкнено. Ви більше не отримуватиме це питання знову."
                    ;;
                *)
                    title="One-time question about helping Winetricks development"
                    question="Would you like to help winetricks development by letting winetricks report statistics? You can turn reporting off at any time with the command 'winetricks --optout'"
                    thanks="Thanks! You won't be asked this question again. Remember, you can turn reporting off at any time with the command 'winetricks --optout'"
                    declined="OK, winetricks will *not* report statistics. You won't be asked this question again."
                    ;;
                esac
                if $WINETRICKS_GUI --question --text "$question" --title "$title"; then
                    $WINETRICKS_GUI --info --text "$thanks"
                    WINETRICKS_STATS_REPORT=1
                else
                    $WINETRICKS_GUI --info --text "$declined"
                    WINETRICKS_STATS_REPORT=0
                fi
                winetricks_stats_save
                ;;
        esac
    fi
}

# Retrieve a short string with the operating system name and version
winetricks_os_description()
{
    (
        case "$W_PLATFORM" in
            windows_cmd) echo "windows" ;;
            *)  echo "$WINETRICKS_WINE_VERSION" ;;
        esac
    ) | tr '\012' ' '
}

winetricks_stats_report()
{
    winetricks_download_setup

    # If user has opted in to usage tracking, report what he used (if anything)
    case "$WINETRICKS_STATS_REPORT" in
        1) ;;
        *) return;;
    esac

    BREADCRUMBS_FILE="$WINETRICKS_WORKDIR"/breadcrumbs
    if test -f "$BREADCRUMBS_FILE"; then
        WINETRICKS_STATS_BREADCRUMBS=$(tr '\012' ' ' < "$BREADCRUMBS_FILE")
        echo "You opted in, so reporting '$WINETRICKS_STATS_BREADCRUMBS' to the winetricks maintainer so he knows which winetricks verbs get used and which don't.  Use --optout to disable future reports."

        report="os=$(winetricks_os_description)&winetricks=$WINETRICKS_VERSION&breadcrumbs=$WINETRICKS_STATS_BREADCRUMBS"
        report="$(echo "$report" | sed 's/ /%20/g')"

        # Just do a HEAD request with the raw command line.
        # Yes, this can be fooled by caches.  That's ok.

        # Note: these downloads are expected to fail (the resource won't exist), so don't use w_try and use '|| true' to ignore the expected errors
        if [ "${WINETRICKS_DOWNLOADER}" = "wget" ] ; then
            $torify wget --timeout "${WINETRICKS_DOWNLOADER_TIMEOUT}" \
                --tries "$WINETRICKS_DOWNLOADER_RETRIES" \
                --spider "http://kegel.com/data/winetricks-usage?$report" > /dev/null 2>&1 || true
        elif [ "${WINETRICKS_DOWNLOADER}" = "curl" ] ; then
            $torify curl --connect-timeout "${WINETRICKS_DOWNLOADER_TIMEOUT}" \
            --retry "$WINETRICKS_DOWNLOADER_RETRIES" \
            -I "http://kegel.com/data/winetricks-usage?$report" > /dev/null 2>&1 || true
        elif [ "${WINETRICKS_DOWNLOADER}" = "aria2c" ] ; then
            $torify aria2c $aria2c_torify_opts \
                    $aria2c_torify_opts \
                    --connect-timeout="${WINETRICKS_DOWNLOADER_TIMEOUT}" \
                    --daemon=false \
                    --enable-rpc=false \
                    --input-file='' \
                    --max-tries="$WINETRICKS_DOWNLOADER_RETRIES" \
                    --save-session='' \
                    "http://kegel.com/data/winetricks-usage?$report" > /dev/null 2>&1 || true
        else
            w_die "Here be dragons"
        fi
    fi
}

winetricks_stats_log_command()
{
    # log what we execute for possible later statistics reporting
    echo "$*" >> "$WINETRICKS_WORKDIR"/breadcrumbs

    # and for the user's own reference later, when figuring out what he did
    case "$W_PLATFORM" in
        windows_cmd) _W_LOGDIR="$W_WINDIR_UNIX"/Temp ;;
        *) _W_LOGDIR="$WINEPREFIX" ;;
    esac

    mkdir -p "$_W_LOGDIR"
    echo "$*" >> "$_W_LOGDIR"/winetricks.log
    unset _W_LOGDIR
}

# Launch a new terminal window if in GUI, or
# spawn a shell in the current window if command line.
# New shell contains proper WINEPREFIX and WINE environment variables.
# May be useful when debugging verbs.
winetricks_shell()
{
    (
        w_try_cd "$W_DRIVE_C"
        export WINE

        case $WINETRICKS_GUI in
            none)
                $SHELL
                ;;
            *)
                for term in gnome-terminal konsole Terminal xterm; do
                    if test "$(command -v $term 2>/dev/null)"; then
                        $term
                        break
                    fi
                done
                ;;
            esac
    )
}

# Usage: execute_command verb[=argument]
execute_command()
{
    case "$1" in
        *=*) arg=$(echo "$1" | sed 's/.*=//'); cmd=$(echo "$1" | sed 's/=.*//');;
        *) cmd="$1"; arg="" ;;
    esac

    case "$1" in
        # FIXME: avoid duplicated code
        apps|benchmarks|dlls|fonts|games|prefix|settings)
            WINETRICKS_CURMENU="$1"
            ;;

        # Late options
        -*)
            if ! winetricks_handle_option "$1"; then
                winetricks_usage
                exit 1
            fi
            ;;

        # Hard-coded verbs
        main) WINETRICKS_CURMENU=main ;;
        help) w_open_webpage https://github.com/Winetricks/winetricks/wiki ;;
        list) winetricks_list_all ;;
        list-cached) winetricks_list_cached ;;
        list-download) winetricks_list_download ;;
        list-manual-download) winetricks_list_manual_download ;;
        list-installed) winetricks_list_installed ;;
        list-all)
            old_menu="$WINETRICKS_CURMENU"
            for WINETRICKS_CURMENU in apps benchmarks dlls fonts games prefix settings; do
                echo "===== $WINETRICKS_CURMENU ====="
                winetricks_list_all
            done
            WINETRICKS_CURMENU="$old_menu"
            ;;
        unattended) winetricks_set_unattended 1 ;;
        attended) winetricks_set_unattended 0 ;;
        arch=*) winetricks_set_winearch "$arg" ;;
        prefix=*) winetricks_set_wineprefix "$arg" ;;
        annihilate) winetricks_annihilate_wineprefix ;;
        folder) w_open_folder "$WINEPREFIX" ;;
        winecfg) "$WINE" winecfg ;;
        regedit) "$WINE" regedit ;;
        taskmgr) "$WINE" taskmgr & ;;
        explorer) "$WINE" explorer & ;;
        uninstaller) "$WINE" uninstaller ;;
        shell) winetricks_shell ;;

        # These have to come before *=disabled to avoid looking like DLLs
        fontsmooth=disable*) w_call fontsmooth=disable ;;
        glsl=disable*) w_call glsl=disabled ;;
        multisampling=disable*) w_call multisampling=disabled ;;
        mwo=disable*) w_call mwo=disable ;;   # FIXME: relax matching so we can handle these spelling differences in verb instead of here
        rtlm=disable*) w_call rtlm=disabled ;;
        sound=disable*) w_call sound=disabled ;;
        ao=disable*) w_call ao=disabled ;;
        strictdrawordering=disable*) w_call strictdrawordering=disabled ;;

        # Use winecfg if you want a GUI for plain old DLL overrides
        alldlls=*) w_call "$1" ;;
        *=native) w_do_call native "$cmd";;
        *=builtin) w_do_call builtin "$cmd";;
        *=default) w_do_call default "$cmd";;
        *=disabled) w_do_call disabled "$cmd";;
        vd=*) w_do_call "$cmd";;

        # Hacks for backwards compatibility
        # 2017/03/22: add deprecation notices
        cc580) w_warn "Calling cc580 is deprecated, please use comctl32 instead" ; w_call comctl32 ;;
        comdlg32.ocx) w_warn "Calling comdlg32.ocx is deprecated, please use comdlg32ocx instead" ; w_call comdlg32ocx ;;
        dotnet1) w_warn "Calling dotnet1 is deprecated, please use dotnet11 instead" ; w_call dotnet11 ;;
        dotnet2) w_warn "Calling dotnet2 is deprecated, please use dotnet20 instead" ; w_call dotnet20 ;;
        d9vk_master) w_warn "Calling d9vk_master is deprecated, please use dxvk_master instead" ; w_call dxvk_master ;;
        dxvk54) w_warn "Calling dxvk54 is deprecated, please use dxvk054 instead" ; w_call dxvk054 ;;
        dxvk60) w_warn "Calling dxvk60 is deprecated, please use dxvk060 instead" ; w_call dxvk060 ;;
        dxvk61) w_warn "Calling dxvk61 is deprecated, please use dxvk061 instead" ; w_call dxvk061 ;;
        dxvk62) w_warn "Calling dxvk62 is deprecated, please use dxvk062 instead" ; w_call dxvk062 ;;
        dxvk63) w_warn "Calling dxvk63 is deprecated, please use dxvk063 instead" ; w_call dxvk063 ;;
        dxvk64) w_warn "Calling dxvk64 is deprecated, please use dxvk064 instead" ; w_call dxvk064 ;;
        dxvk65) w_warn "Calling dxvk65 is deprecated, please use dxvk065 instead" ; w_call dxvk065 ;;
        dxvk70) w_warn "Calling dxvk70 is deprecated, please use dxvk070 instead" ; w_call dxvk070 ;;
        dxvk71) w_warn "Calling dxvk71 is deprecated, please use dxvk071 instead" ; w_call dxvk071 ;;
        dxvk72) w_warn "Calling dxvk72 is deprecated, please use dxvk072 instead" ; w_call dxvk072 ;;
        dxvk80) w_warn "Calling dxvk80 is deprecated, please use dxvk080 instead" ; w_call dxvk080 ;;
        dxvk81) w_warn "Calling dxvk81 is deprecated, please use dxvk081 instead" ; w_call dxvk081 ;;
        dxvk90) w_warn "Calling dxvk90 is deprecated, please use dxvk090 instead" ; w_call dxvk090 ;;
        dxvk91) w_warn "Calling dxvk91 is deprecated, please use dxvk091 instead" ; w_call dxvk091 ;;
        dxvk92) w_warn "Calling dxvk92 is deprecated, please use dxvk092 instead" ; w_call dxvk092 ;;
        dxvk93) w_warn "Calling dxvk93 is deprecated, please use dxvk093 instead" ; w_call dxvk093 ;;
        dxvk94) w_warn "Calling dxvk94 is deprecated, please use dxvk094 instead" ; w_call dxvk094 ;;
        dxvk95) w_warn "Calling dxvk95 is deprecated, please use dxvk095 instead" ; w_call dxvk095 ;;
        dxvk96) w_warn "Calling dxvk96 is deprecated, please use dxvk096 instead" ; w_call dxvk096 ;;
        flash11) w_warn "Calling flash11 is deprecated, please use flash instead" ; w_call flash ;;
        # art2kmin also comes with fm20.dll
        fm20) w_warn "Calling fm20 is deprecated, please use controlpad instead" ; w_call controlpad ;;
        fontsmooth-bgr) w_warn "Calling fontsmooth-bgr is deprecated, please use fontsmooth=bgr instead" ; w_call fontsmooth=bgr ;;
        fontsmooth-disable) w_warn "Calling fontsmooth-disable is deprecated, please use fontsmooth=disable instead" ; w_call fontsmooth=disable ;;
        fontsmooth-gray) w_warn "Calling fontsmooth-gray is deprecated, please use fontsmooth=gray instead" ; w_call fontsmooth=gray ;;
        fontsmooth-rgb) w_warn "Calling fontsmooth-rgb is deprecated, please use fontsmooth=rgb instead" ; w_call fontsmooth=rgb ;;
        glsl-disable) w_warn "Calling glsl-disable is deprecated, please use glsl=disabled instead" ; w_call glsl=disabled ;;
        glsl-enable) w_warn "Calling glsl-enable is deprecated, please use glsl=enabled instead" ; w_call glsl=enabled ;;
        ie6_full) w_warn "Calling ie6_full is deprecated, please use ie6 instead" ; w_call ie6 ;;
        # FIXME: use wsh57 instead?
        jscript) w_warn "Calling jscript is deprecated, please use wsh57 instead" ; w_call wsh57 ;;
        npm-repack) w_warn "Calling npm-repack is deprecated, please use npm=repack instead" ; w_call npm=repack ;;
        oss) w_warn "Calling oss is deprecated, please use sound=oss instead" ; w_call sound=oss ;;
        python) w_warn "Calling python is deprecated, please use python26 instead" ; w_call python26 ;;
        vbrun60) w_warn "Calling vbrun60 is deprecated, please use vb6run instead" ; w_call vb6run ;;
        vcrun2005sp1) w_warn "Calling vcrun2005sp1 is deprecated, please use vcrun2005 instead" ; w_call vcrun2005 ;;
        vcrun2008sp1) w_warn "Calling vcrun2008sp1 is deprecated, please use vcrun2008 instead" ; w_call vcrun2008 ;;
        wsh56|wsh56js|wsh56vb) w_warn "Calling wsh56 is deprecated, please use wsh57 instead" ; w_call wsh57 ;;
        # See https://github.com/Winetricks/winetricks/issues/747
        xact_jun2010) w_warn "Calling xact_jun2010 is deprecated, please use xact instead" ; w_call xact ;;
        xlive) w_warn "Calling xlive is deprecated, please use gfw instead" ; w_call gfw ;;

        # Normal verbs, with metadata and load_ functions
        *)
            if winetricks_metadata_exists "$1"; then
                w_call "$1"
            else
                echo "Unknown arg $1"
                winetricks_usage
                exit 1
            fi
            ;;
    esac
}

if ! test "$WINETRICKS_LIB"; then
    # If user opted out, save that preference now.
    winetricks_stats_save

    # If user specifies menu on command line, execute that command, but don't commit to command-line mode
    # FIXME: this code is duplicated several times; unify it
    if echo "$WINETRICKS_CATEGORIES" | grep -w "$1" > /dev/null; then
        WINETRICKS_CURMENU=$1
        shift
    fi

    case "$1" in
        die) w_die "we who are about to die salute you." ;;
        volnameof=*)
            # Debug code.  Remove later?
            # Since Linux's volname command can't handle DVDs, winetricks has its own,
            # implemented using dd, old gum, and some string I had laying around.
            # You can try it like this:
            #  winetricks volnameof=/dev/sr0
            # or
            #  winetricks volnameof=foo.iso
            # This will read the volname from the given image and put it to stdout.
            winetricks_volname "${1#volnameof=}"
            ;;
        "")
            if [ -z "$DISPLAY" ]; then
                if [ "$(uname -s)" = "Darwin" ]; then
                    echo "Running on OSX, but DISPLAY is not set...probably using Mac Driver."
                else
                    echo "DISPLAY not set, not defaulting to gui"
                    winetricks_usage
                    exit 0
                fi
            fi

            # GUI case
            # No non-option arguments given, so read them from GUI, and loop until user quits
            winetricks_detect_gui
            winetricks_detect_sudo
            test -z "$WINETRICKS_ISO_MOUNT" && winetricks_detect_iso_mount
            while true; do
                case $WINETRICKS_CURMENU in
                    main) verbs=$(winetricks_mainmenu) ;;
                    prefix)
                        verbs=$(winetricks_prefixmenu);
                        # Cheezy hack: choosing 'attended' or 'unattended' leaves you in same menu
                        case "$verbs" in
                            attended) winetricks_set_unattended 0 ; continue;;
                            unattended) winetricks_set_unattended 1 ; continue;;
                        esac
                        ;;
                    mkprefix) verbs=$(winetricks_mkprefixmenu) ;;
                    settings) verbs=$(winetricks_settings_menu) ;;
                    *) verbs="$(winetricks_showmenu)" ;;
                esac

                if test "$verbs" = ""; then
                    # "user didn't pick anything, back up a level in the menu"
                    case "${WINETRICKS_CURMENU}-${WINETRICKS_OPT_SHAREDPREFIX}" in
                        apps-0|benchmarks-0|games-0|main-*) WINETRICKS_CURMENU=prefix ;;
                        prefix-*) break ;;
                        *) WINETRICKS_CURMENU=main ;;
                    esac
                elif echo "$WINETRICKS_CATEGORIES" | grep -w "$verbs" > /dev/null; then
                    WINETRICKS_CURMENU=$verbs
                else
                    winetricks_stats_init
                    # Otherwise user picked one or more real verbs.
                    case "$verbs" in
                        prefix=*|arch=*)
                            # prefix menu is special, it only returns one verb, and the
                            # verb can contain spaces. If a 32bit wineprefix is created via
                            # the GUI, this may have an "arch=* " prefix
                            _W_arch=$(echo "$verbs" | grep -o 'arch=.*' | cut -d' ' -f1)
                            _W_prefix=$(echo "$verbs" | grep -o 'prefix=.*')
                            _W_prefix_name="${_W_prefix#*=}"
                            if [ -n "$_W_arch" ]; then
                                execute_command "$_W_arch"
                            fi
                            execute_command "$_W_prefix"
                            # after picking a prefix, want to land in main.
                            WINETRICKS_CURMENU=main ;;
                        *)
                            for verb in $verbs; do
                                execute_command "$verb"
                            done

                            case "${WINETRICKS_CURMENU}-${WINETRICKS_OPT_SHAREDPREFIX}" in
                                prefix-*|apps-0|benchmarks-0|games-0)
                                    # After installing isolated app, return to prefix picker
                                    WINETRICKS_CURMENU=prefix
                                    ;;
                                *)
                                    # Otherwise go to main menu.
                                    WINETRICKS_CURMENU=main
                                    ;;
                            esac
                            ;;
                    esac
                fi
            done
            ;;
        *)
            winetricks_stats_init
            # Command-line case
            winetricks_detect_sudo
            test -z "$WINETRICKS_ISO_MOUNT" && winetricks_detect_iso_mount
            # User gave command-line arguments, so just run those verbs and exit
            for verb; do
                case $verb in
                    *.verb)
                        # Load the verb file
                        # shellcheck disable=SC1090
                        case $verb in
                            */*) . "$verb" ;;
                            *) . ./"$verb" ;;
                        esac

                        # And forget that the verb comes from a file
                        verb="$(echo "$verb" | sed 's,.*/,,;s,.verb,,')"
                        ;;
                esac
                execute_command "$verb"
            done
            ;;
    esac

    winetricks_stats_report
fi

# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
